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
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.
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.