Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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 #178

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

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.

None yet

3 participants