Closed joeltg closed 2 years ago
willfix, thanks for the clear writeup.
I left a couple of comments on the PR for you to double-check my work, if you please. Sorry the patch is so large, I wanted to regen docs etc so I'm ready to do a release once you sign off.
Fixed in 8.0.2
This is a niche issue relating to just the value
- 2^53
The CBOR spec, in the section on converting JSON to CBOR, says
And sure enough, there's a check on this line to make sure that integers greater than
Number.MAX_SAFE_INTEGER
get encoded as floats, not as integer types. However this check happens after negative integer values are mapped to positive integer values. This means there's an offset of 1 for negative integers that isn't accounted for when checking if they're safe or not.For example the safe integer
Number.MIN_SAFE_INTEGER
gets mapped to- Number.MIN_SAFE_INTEGER - 1 = 9007199254740990 = Math.pow(2, 53) - 2
, whichnode-cbor
correctly encodes as a major type 1 with a uint64 argument. But the unsafe integerNumber.MIN_SAFE_INTEGER - 1
gets mapped to- (Number.MIN_SAFE_INTEGER - 1) - 1 = 9007199254740991 = Math.pow(2, 53) - 1
, whichnode-cbor
thinks is a safe integer value since it's less than or equal toNumber.MAX_SAFE_INTEGER
.Hopefully that made sense. Concretely, these three numbers encode as expected:
But this behavior is not expected: