From 011eb1e4245c230fb3e26b0426e7a011f8db75ba Mon Sep 17 00:00:00 2001 From: Tatiana Borisova Date: Thu, 20 Aug 2026 13:24:37 +0200 Subject: [PATCH] Fix topic alias bounds and storage sizes - In the f8ecf4d56a3a955c7f11db1fa32dada9dfcfb8e6 we found that the m_receiveAliases bounds check used a wrong property: m_clientPrivate->m_serverConnectionProperties.maximumTopicAlias(), but it must use instead: m_clientPrivate->m_connectionProperties.maximumTopicAlias(). So, the idea is m_receiveAliases is sized according to the maximum topic alias value declared by the client in CONNECT, while m_publishAliases is sized according to the maximum value declared by the server in CONNACK. The previous fix did not update all related code. 1) The resize() calls for m_receiveAliases and m_publishAliases still used the wrong properties. 2) The bounds check for m_publishAliases still used the client's maximumTopicAlias() value instead of the server's. - Update the resize() calls to use the appropriate connection properties and fix the bounds check for m_publishAliases. Amends f8ecf4d56a3a955c7f11db1fa32dada9dfcfb8e6 Pick-to: 6.11 6.12 6.8 Task-number: QTBUG-149564 Change-Id: I252c67966bf28c6994f34b19024d1b7894748473 Reviewed-by: Ivan Solovev --- src/mqtt/qmqttconnection.cpp | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/mqtt/qmqttconnection.cpp b/src/mqtt/qmqttconnection.cpp index 5138d97..9df21da 100644 --- a/src/mqtt/qmqttconnection.cpp +++ b/src/mqtt/qmqttconnection.cpp @@ -472,7 +472,9 @@ qint32 QMqttConnection::sendControlPublish(const QMqttTopicName &topic, const quint16 topicAlias = publishProperties.topicAlias(); if (topicAlias > 0) { // User specified topic Alias - if (topicAlias > m_clientPrivate->m_serverConnectionProperties.maximumTopicAlias()) { + // m_publishAliases is sized from the maximum the server declared in CONNACK, + // so bounds-check against the list itself rather than against a property value. + if (topicAlias > m_publishAliases.size()) { qCDebug(lcMqttConnection) << "TopicAlias publish: overflow."; return -1; } @@ -1571,8 +1573,16 @@ void QMqttConnection::finalize_connack() // property length. Do not overwrite the state of a connection which is gone. if (m_internalState == BrokerDisconnected) return; - m_receiveAliases.resize(m_clientPrivate->m_serverConnectionProperties.maximumTopicAlias()); - m_publishAliases.resize(m_clientPrivate->m_connectionProperties.maximumTopicAlias()); + // MQTT 5.0, 3.1.2.11.5 and 3.2.2.3.8: the two Topic Alias Maximum values are + // directional. The value this client sent in CONNECT bounds the aliases the + // server may use towards us (m_receiveAliases); the value the server sent in + // CONNACK bounds the aliases we may use towards it (m_publishAliases). + // Mappings live only for the lifetime of a network connection, so discard any + // left over from a previous one instead of resizing in place. + m_receiveAliases.clear(); + m_receiveAliases.resize(m_clientPrivate->m_connectionProperties.maximumTopicAlias()); + m_publishAliases.clear(); + m_publishAliases.resize(m_clientPrivate->m_serverConnectionProperties.maximumTopicAlias()); // 3.2.2.2 switch (QMqtt::ReasonCode(connectResultValue)) { @@ -1756,7 +1766,9 @@ void QMqttConnection::finalize_publish() if (publishProperties.availableProperties() & QMqttPublishProperties::TopicAlias) { const quint16 topicAlias = publishProperties.topicAlias(); - if (topicAlias == 0 || topicAlias > m_clientPrivate->m_connectionProperties.maximumTopicAlias()) { + // m_receiveAliases is sized from the maximum this client declared in CONNECT, + // so bounds-check against the list itself rather than against a property value. + if (topicAlias == 0 || topicAlias > m_receiveAliases.size()) { qCDebug(lcMqttConnection) << "TopicAlias receive: overflow."; closeConnection(QMqttClient::ProtocolViolation); return;