-
Bug
-
Resolution: Fixed
-
P2: Important
-
6.8.2
-
None
-
3
-
c6452e4ee (dev), 22c21ea88 (6.9), 81be4026a (tqtc/lts-6.8), 46ee510ae (tqtc/lts-6.5)
-
Foundation Sprint 130
Here's a short version of the code:
void waitFinished (QModbusReply *reply)
{
// ...
QModbusRequest modbusRequest(QModbusRequest::MaskWriteRegister, request);
auto reply = client->sendRawRequest(modbusRequest, macAddr);
if (!reply) {
return false;
}
if (!reply->isFinished()) {
QEventLoop loop;
connect(this, &Engine::sigCancel, &loop, &QEventLoop::quit);
connect(reply, &QModbusReply::finished, &loop, &QEventLoop::quit);
loop.exec();
}
reply->deleteLater();
if (cancel_task) {
LOG_WARN("Task canceled");
return false;
}
// do other things...
}
- If through the initiative to cancel
- reply would be deleted
- lead to QModbusRtuSerialClientPrivate: : onReadyRead crash because of wild pointer
Qt Code analysis:
bool QModbusRtuSerialClientPrivate::canMatchRequestAndResponse(const QModbusResponse& response, int sendingServer) const { if (m_queue.isEmpty()) return false; const auto& current = m_queue.first(); if (current.reply.isNull()) return false; // reply deleted if (current.reply->serverAddress() != sendingServer) return false; // server mismatch if (current.requestPdu.functionCode() != response.functionCode()) return false; // request for different function code return true; }
void QModbusRtuSerialClientPrivate::onReadyRead() {
// ...
const QModbusResponse response = adu.pdu();
if (!canMatchRequestAndResponse(response, adu.serverAddress())) {
qCWarning(QT_MODBUS) << "(RTU client) Cannot match response with open request, "
"ignoring";
m_queue.first().reply->addIntermediateError(QModbusClient::ResponseRequestMismatch);
return;
}
// ...
}
- canMatchRequestAndResponse return false, because of "current.reply.isNull()"
- in onReadyRead function, no test whether the pointer(m_queue.first().reply) is null
- access the pointer m_queue.first().reply directly, Cause a crash