@@ -96,6 +96,22 @@ static uint8_t *stringprint(uint8_t *p, const char *s, uint16_t maxlen = 0) {
9696 return p + len;
9797}
9898
99+ // packetAdditionalLen is a helper function used to figure out
100+ // how bigger the payload needs to be in order to account for
101+ // its variable length field. As per
102+ // http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Table_2.4_Size
103+ // See also readFullPacket
104+ static uint16_t packetAdditionalLen (uint32_t currLen) {
105+ /* Increase length field based on current length */
106+ if (currLen < 128 ) // 7-bits
107+ return 0 ;
108+ if (currLen < 16384 ) // 14-bits
109+ return 1 ;
110+ if (currLen < 2097152 ) // 21-bits
111+ return 2 ;
112+ return 3 ;
113+ }
114+
99115// Adafruit_MQTT Definition ////////////////////////////////////////////////////
100116
101117Adafruit_MQTT::Adafruit_MQTT (const char *server, uint16_t port, const char *cid,
@@ -233,7 +249,7 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize,
233249 // will read a packet and Do The Right Thing with length
234250 uint8_t *pbuff = buffer;
235251
236- uint8_t rlen;
252+ uint16_t rlen;
237253
238254 // read the packet type:
239255 rlen = readPacket (pbuff, 1 , timeout);
@@ -267,7 +283,8 @@ uint16_t Adafruit_MQTT::readFullPacket(uint8_t *buffer, uint16_t maxsize,
267283 DEBUG_PRINT (F (" Packet Length:\t " ));
268284 DEBUG_PRINTLN (value);
269285
270- if (value > (maxsize - (pbuff - buffer) - 1 )) {
286+ // maxsize is limited to 65536 by 16-bit unsigned
287+ if (value > uint32_t (maxsize - (pbuff - buffer) - 1 )) {
271288 DEBUG_PRINTLN (F (" Packet too big for buffer" ));
272289 rlen = readPacket (pbuff, (maxsize - (pbuff - buffer) - 1 ), timeout);
273290 } else {
@@ -492,7 +509,9 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
492509 }
493510
494511 // Parse out length of packet.
495- topiclen = buffer[3 ];
512+ uint16_t const topicoffset = packetAdditionalLen (len);
513+ uint16_t const topicstart = topicoffset + 4 ;
514+ topiclen = buffer[3 + topicoffset];
496515 DEBUG_PRINT (F (" Looking for subscription len " ));
497516 DEBUG_PRINTLN (topiclen);
498517
@@ -505,8 +524,8 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
505524 continue ;
506525 // Stop if the subscription topic matches the received topic. Be careful
507526 // to make comparison case insensitive.
508- if (strncasecmp ((char *)buffer + 4 , subscriptions[i]->topic , topiclen) ==
509- 0 ) {
527+ if (strncasecmp ((char *)buffer + topicstart , subscriptions[i]->topic ,
528+ topiclen) == 0 ) {
510529 DEBUG_PRINT (F (" Found sub #" ));
511530 DEBUG_PRINTLN (i);
512531 break ;
@@ -521,21 +540,21 @@ Adafruit_MQTT_Subscribe *Adafruit_MQTT::handleSubscriptionPacket(uint16_t len) {
521540 // Check if it is QoS 1, TODO: we dont support QoS 2
522541 if ((buffer[0 ] & 0x6 ) == 0x2 ) {
523542 packet_id_len = 2 ;
524- packetid = buffer[topiclen + 4 ];
543+ packetid = buffer[topiclen + topicstart ];
525544 packetid <<= 8 ;
526- packetid |= buffer[topiclen + 5 ];
545+ packetid |= buffer[topiclen + topicstart + 1 ];
527546 }
528547
529548 // zero out the old data
530549 memset (subscriptions[i]->lastread , 0 , SUBSCRIPTIONDATALEN);
531550
532- datalen = len - topiclen - packet_id_len - 4 ;
551+ datalen = len - topiclen - packet_id_len - topicstart ;
533552 if (datalen > SUBSCRIPTIONDATALEN) {
534553 datalen = SUBSCRIPTIONDATALEN - 1 ; // cut it off
535554 }
536555 // extract out just the data, into the subscription object itself
537- memmove (subscriptions[i]->lastread , buffer + 4 + topiclen + packet_id_len,
538- datalen);
556+ memmove (subscriptions[i]->lastread ,
557+ buffer + topicstart + topiclen + packet_id_len, datalen);
539558 subscriptions[i]->datalen = datalen;
540559 DEBUG_PRINT (F (" Data len: " ));
541560 DEBUG_PRINTLN (datalen);
@@ -669,21 +688,6 @@ uint8_t Adafruit_MQTT::connectPacket(uint8_t *packet) {
669688 return len;
670689}
671690
672- // packetAdditionalLen is a helper function used to figure out
673- // how bigger the payload needs to be in order to account for
674- // its variable length field. As per
675- // http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Table_2.4_Size
676- static uint16_t packetAdditionalLen (uint16_t currLen) {
677- /* Increase length field based on current length */
678- if (currLen < 128 )
679- return 0 ;
680- if (currLen < 16384 )
681- return 1 ;
682- if (currLen < 2097151 )
683- return 2 ;
684- return 3 ;
685- }
686-
687691// as per
688692// http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718040
689693uint16_t Adafruit_MQTT::publishPacket (uint8_t *packet, const char *topic,
0 commit comments