@@ -562,15 +562,33 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
562562 return NULL ;
563563 }
564564
565- // Parse out length of packet.
566- // NOTE: This includes data in the variable header and the payload.
567- uint16_t remainingLen = len - 4 ; // subtract the 4 header bytes
568- uint16_t const topicoffset = packetAdditionalLen (remainingLen);
569- uint16_t const topicstart = topicoffset + 4 ;
570-
571- topiclen = int ((buffer[2 + topicoffset]) << 8 | buffer[3 + topicoffset]);
572- DEBUG_PRINT (F (" Looking for subscription len " ));
573- DEBUG_PRINTLN (topiclen);
565+ // Parse MQTT Remaining Length field (variable length encoding).
566+ // This field can be 1-4 bytes, so we must parse it byte-by-byte.
567+ // Each byte uses the lower 7 bits for data, and the MSB as a continuation
568+ // flag. This loop advances 'offset' to the first byte after the remaining
569+ // length field.
570+ uint32_t multiplier = 1 ;
571+ uint32_t value = 0 ;
572+ uint8_t encodedByte;
573+ uint8_t offset = 1 ; // Start after the fixed header byte
574+ do {
575+ encodedByte = buffer[offset++];
576+ value += (encodedByte & 127 ) * multiplier;
577+ multiplier *= 128 ;
578+ // Infinite loop protection: MQTT spec allows max 4 bytes for this field
579+ if (offset > 5 ) { // 1 (header) + 4 (max length bytes)
580+ DEBUG_PRINTLN (
581+ F (" Bad MQTT packet: Remaining Length field too long / malformed" ));
582+ return NULL ;
583+ }
584+ } while ((encodedByte & 128 ) != 0 );
585+
586+ // Now 'offset' points to the first byte of the topic length field.
587+ // The topic length is always 2 bytes, big-endian.
588+ uint16_t new_msb = buffer[offset] << 8 ;
589+ uint16_t new_lsb = buffer[offset + 1 ];
590+ topiclen = new_msb | new_lsb;
591+ uint16_t topicstart = offset + 2 ;
574592
575593 // Find subscription associated with this packet.
576594 for (i = 0 ; i < MAXSUBSCRIPTIONS; i++) {
0 commit comments