blob: 00309466feee875a698fe8096e904cd22b818971 [file] [log] [blame]
Patch Notes:
============
[Bug 546045] MQTT Decoding of remaining length (https://bugs.eclipse.org/bugs/show_bug.cgi?id=546045)
Issue:
In the MQTT v3.1.1 specification section 2.2.3 [1] the description of the variable length encoding states, that the remaining length can be encoded with up to 4 bytes. However, the shown decoding algorithm (non-normative comment) fails to decode all remaining lengths which are encoded with 4 bytes (all above 2097151B respectively 0xFF 0xFF 0x7F).
Example:
========
For example, the smallest remaining length which is encoded with 4 bytes according to Table 2.4 in [1] is 2097152. Let's examine this case with the given algorithm.
>> Pre condition:
let input_encoded_bytes[4] = [0x80, 0x80, 0x80, 0x01] // -> as ui32 = 2097152
let multiplier = 1
let value = 0
>> Iteration 1:
let encoded_byte = 0x80
value = 0 + (encoded_byte AND 0x7F) * 1 // => value = 0
multiplier = 1 * 128
if (multiplier > 128 * 128 * 128) { throw Error } // no Error
>> Iteration 2: [(encoded_byte AND 0x80) != 0]
let encoded_byte = 0x80
value = 0 + (encoded_byte AND 0x7F) * 128 // => value = 0
multiplier = 128 * 128
if (multiplier > 128 * 128 * 128) { throw Error } // no Error
>> Iteration 3: [(encoded_byte AND 0x80) != 0]
let encoded_byte = 0x80
value = 0 + (encoded_byte AND 0x7F) * 128 * 128 // => value = 0
multiplier = 128 * 128 * 128
if (multiplier > 128 * 128 * 128) { throw Error } // no Error
>> Iteration 4: [(encoded_byte AND 0x80) != 0]
let encoded_byte = 0x01
value = 0 + (encoded_byte AND 0x7F) * 128 * 128 * 128 // => value = 2097152
multiplier = 128 * 128 * 128 * 128
if (multiplier > 128 * 128 * 128) { throw Error } // Error!
As one can see, although the value is correctly decoded, the algorithm throws an error after decoding the 4th byte.
Solution:
=========
The MQTT v5 specification provides in [2] a small bugfix for this algorithm. This fix affects only the 4th iteration from the previous example.
>> Iteration 4 (fixed): [(encoded_byte AND 0x80) != 0]
let encoded_byte = 0x01
value = 0 + (encoded_byte AND 0x7F) * 128 * 128 * 128 // => value = 2097152
if (multiplier > 128 * 128 * 128) { throw Error } // no Error
multiplier = 128 * 128 * 128 * 128
if ((encoded_byte AND 0x80) != 0) { end of do-while loop } // correctly terminated decoding with value = 2097152
[1] http://docs.oasis-open.org/mqtt/mqtt/v3.1.1/os/mqtt-v3.1.1-os.html#_Toc398718023
[2] http://docs.oasis-open.org/mqtt/mqtt/v5.0/csprd01/mqtt-v5.0-csprd01.html#_Toc489530042