Documentation and cleanup fixes#376
Merged
AniruddhaKanhere merged 6 commits intoJul 6, 2026
Merged
Conversation
AniruddhaKanhere
force-pushed
the
documentation-and-cleanup-fixes
branch
2 times, most recently
from
July 2, 2026 00:09
2ce273d to
7593ea5
Compare
archigup
previously approved these changes
Jul 2, 2026
AniruddhaKanhere
force-pushed
the
documentation-and-cleanup-fixes
branch
from
July 2, 2026 20:21
548ba4b to
20d5248
Compare
Corrects Doxygen comments and in-comment code examples reported by review: - transport_interface.h: TransportWritev_t doc referenced nonexistent TransportIoVector_t (should be TransportOutVector_t). - core_mqtt.h: missing comma in MQTT_GetSubAckStatusCodes example callback; MQTT_InitRetransmits example prototypes matched to the actual retransmit typedefs; SubAck/UnsubAck example loops use size_t index; removed empty MQTT_CheckConnectStatus example block; replaced VLA-from-const in the Init examples with a literal size; clarified SUBACK reason-code note. - core_mqtt_serializer.h: examples use uint32_t (not size_t) for remainingLength/packetSize out-params; added missing maxPacketSize args to Get*PacketSize example calls; fixed MQTT_ValidatePublishParams example arg order; MQTT_DeserializeAck pConnectProperties tag is @param[in] (const); declared packetSize in the SerializePingreq example; dropped the misleading 'CONNACK' mention from the MQTT_DeserializeAck reason-code comment. Comment-only changes; no executable code affected.
- addPropUint16/addPropUint32 (core_mqtt_prop_serializer.c): the shared
helpers logged a hardcoded property name ("Receive Maximum"/"Subscription
Id") for every property they serialize; log the actual propId instead.
- MQTT_SerializePublishHeader (core_mqtt_serializer.c): the buffer-too-small
log subtracted payloadLength from packetSize, which already excludes the
payload, causing a size_t underflow in the message; log packetSize directly.
- MQTT_GetDisconnectPacketSize (core_mqtt_serializer.c): accept a remaining
length exactly equal to MQTT_MAX_REMAINING_LENGTH (inclusive max), matching
calculateSubscriptionPacketSize's boundary handling.
- MQTT_ValidateSubscribeProperties (core_mqtt_serializer.c): advance pLocalIndex
past the decoded Subscription Identifier (matching deserializePublishProperties)
so subsequent properties are not misparsed.
- sendUnsubscribeWithoutCopy (core_mqtt.c): bound the property-buffer length
against MQTT_MAX_PACKET_SIZE (as the per-topic branch and sendPublishWithoutCopy
do) instead of MQTT_MAX_REMAINING_LENGTH.
Memory safety re-verified via the MQTT_GetDisconnectPacketSize,
MQTT_ValidateSubscribeProperties, and MQTT_Unsubscribe CBMC proofs.
MQTT_Connect capped incomingPublishRecordMaxCount / outgoingPublishRecordMaxCount at the negotiated Receive Maximum by comparing against, and overwriting, the same field. Because the field was only ever lowered and never restored, the limits shrank monotonically across reconnects: after connecting to a broker advertising a small Receive Maximum, a later reconnect to a broker advertising a larger one kept the smaller cap for the life of the context, wrongly throttling concurrent QoS1/QoS2 publishes. Store the application-configured counts (from MQTT_InitStatefulQoS) separately in new MQTTContext_t fields and, on every successful connect, reset the effective limits to those configured values before applying the negotiated minimum. This matches the behavior the surrounding comment already described. Memory safety re-verified via the MQTT_InitStatefulQoS CBMC proof (the MQTT_Connect proof does not build locally due to a pre-existing CBMC 6.9.0 stub declaration conflict in deserialize_helpers_stubs.c, unrelated to this change).
For QoS>0, MQTT_Publish reserved an outgoing publish record via MQTT_ReserveState and then called sendPublishWithoutCopy(). If that send failed, the state update (MQTT_UpdateStatePublish) was skipped, but the reserved record was never released. compactRecords() only reclaims MQTT_PACKET_ID_INVALID slots, so the MQTTPublishSend record was leaked, and repeated send failures could exhaust the outgoing record pool (MQTTNoMemory) on the reconnect-less retry path. Track whether this call newly reserved a record and, if the send fails, release it with MQTT_RemoveStateRecord while preserving the send-failure status for the caller. Duplicate retransmits (pre-existing records reused via MQTTStateCollision) are left intact, and update-failure after a successful send is unchanged (the packet is in flight). Since the retransmit-store hook runs before the network send, the packet is never transmitted on any sendPublishWithoutCopy failure, so rollback is always safe. Updated two existing store-failure tests to assert the rollback and added a send-failure regression test. Memory safety re-verified via the MQTT_Publish CBMC proof.
kstribrnAmzn
reviewed
Jul 2, 2026
kstribrnAmzn
reviewed
Jul 2, 2026
AniruddhaKanhere
force-pushed
the
documentation-and-cleanup-fixes
branch
from
July 2, 2026 23:40
20d5248 to
56a8397
Compare
kstribrnAmzn
reviewed
Jul 6, 2026
AniruddhaKanhere
force-pushed
the
documentation-and-cleanup-fixes
branch
from
July 6, 2026 20:01
56a8397 to
fc3f6b9
Compare
deserializeSubUnsubAckProperties populated the property buffer's pBuffer and bufferLength but never set currentIndex, unlike its siblings deserializeConnackProperties and deserializePublishProperties. Because the property-get path treats currentIndex as the count of valid bytes (MQTT_GetNextPropertyType / MQTTPropGet_* return MQTTEndOfProperties once the read cursor reaches it), and the caller zero-initializes the buffer, every property in a SUBACK/UNSUBACK (Reason String, User Property) was silently unreadable through the public API. Set currentIndex = propertyLength (matching the sibling deserializers) and reorder the pBuffer/bufferLength assignments to match deserializePublishProperties. Adds a serializer unit test that deserializes a SUBACK carrying a Reason String and asserts it is reachable via MQTT_GetNextPropertyType (fails before this fix). Memory safety re-verified via the deserializeSubUnsubAckProperties CBMC proof.
Per MQTT 5 (sections 3.9 and 3.11) a SUBACK/UNSUBACK payload must contain one reason code per topic filter, so at least one is always present. The library previously accepted a packet whose remaining length was consumed entirely by the packet identifier and properties: - readSubackStatus() looped zero times for statusCount == 0, returned MQTTSuccess and set reasonCodeLength = 0. - MQTT_GetSubAckStatusCodes / MQTT_GetUnsubAckStatusCodes could return MQTTSuccess with *pPayloadSize == 0 and pPayloadStart pointing one past the properties. Reject these malformed packets with MQTTBadResponse in all three places. Adds unit tests: a zero-reason-code SUBACK through MQTT_DeserializeAck (serializer), and zero-payload cases for both public status-code getters. Memory safety re-verified via the MQTT_DeserializeAck, MQTT_GetSubAckStatusCodes and MQTT_GetUnsubAckStatusCodes CBMC proofs.
AniruddhaKanhere
force-pushed
the
documentation-and-cleanup-fixes
branch
from
July 6, 2026 20:17
fc3f6b9 to
8710c3d
Compare
kstribrnAmzn
approved these changes
Jul 6, 2026
AniruddhaKanhere
enabled auto-merge (rebase)
July 6, 2026 20:48
rawalexe
approved these changes
Jul 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Description
Test Steps
Checklist:
Related Issue
By submitting this pull request, I confirm that you can use, modify, copy, and redistribute this contribution, under the terms of your choice.