CBOR Integer Encoding Length Fix #1570
Merged
+225
−11
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.
This PR fixes an issue where the packed length is sub-optimal for all positive integers that have the MSB bit set.
CBOR integers are packed with a set number of bytes, bucketed by length (8bit, 16bit, 32bit etc) determined by the bit length of the source. Negative integers are denoted with a different Major Type (1 for -ve, 0 for +ve) but are otherwise treated as an unsigned value when packing/unpacking.
The original code bucketing check uses the signed
MAX_VALUE
constants which means any values with the MSB set will fall into the next highest bucket, and thus pack into double the expected number of bytes.e.g. 65535 (uint16, all bits high) is encoded with two extra zero bytes as
0x19 0x00 0x00 0xFF 0xFF
whereas it should encode to0x19 0xFF 0xFF
.The RFC does not explicitly state that integers must always pack to the fewest bytes possible, and the format certainly allows it so it is still valid CBOR. e.g. you could pack the value 1 into the space large enough for a 64bit integer and it can still be decoded successfully. However this is certainly at odds with the "C" in "CBOR".