Skip to content

Conversation

@begelundmuller
Copy link

Fixes a bug which caused positive integers between 2^63 to 2^64-1 stored in a bytes.decimal to erroneously decode as negative numbers.

To understand the bug, note that big.Int.BitLen returns the same value for positive and negative numbers. But if the most significant bit of a positive number is on the word boundary, it requires an extra bit to be properly represented in two's complement. The library did not account for that, thus causing some positive numbers to turn negative when casting them to a (signed) int64 -- which doesn't cause an overflow error in Go, see https://play.golang.org/p/hQOopoudJcm.

The bug would have never happened if the library didn't consider decimals with a numerator larger than 64 bits out of bounds, which seems somewhat counterintuitive to the purpose of decimals. So, this fix resolves the bug by not trying to coerce the numerator into an int64.

On that note, unless I'm missing something, it seems to me that a) the library doesn't respect the precision specified in the schema when encoding and decoding values, and b) the library in several places relies on math.Pow10(scale)) fitting in an int64, which is not necessarily the case.

…red in a

bytes.decimal to erroneously decode as negative numbers.

To understand the bug, note that big.Int.BitLen returns the same value for
positive and negative numbers. But if the most significant bit of a positive
number is on the word boundary, it requires an extra bit to be properly
represented in two's complement. The library did not account for that, thus
causing positive numbers to turn negative when casting them to a (signed) int64
-- which doesn't cause an overflow error in Go, see
https://play.golang.org/p/hQOopoudJcm.

The bug would have never happened if the library didn't consider decimals with a
numerator larger than 64 bits out of bounds, which seems somewhat
counterintuitive to the purpose of decimals. So, this fix resolves the bug by
not trying to coerce the numerator into an int64.

On that note, unless I'm missing something, it seems to me that a) the library
doesn't respect the precision specified in the schema when encoding and decoding
values, and b) the library in several places relies on math.Pow10(scale))
fitting in an int64, which is not necessarily the case.
@alexkazantsev
Copy link

Thanks a lot, @begelundmuller! You saved my day!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants