-
Notifications
You must be signed in to change notification settings - Fork 356
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
Fixed integer overflow in NumericDate.MarshalJSON #200
Fixed integer overflow in NumericDate.MarshalJSON #200
Conversation
The original issue was caused by the fact that if we use a very large unix timestamp. The resulting value from time.UnixNano overflows a int64, as documented here: https://pkg.go.dev/time#Time.UnixNano. This patch works around the issue by calculating the second part and nanosecond part separately, taking the second part from time.Unix, and the nanosecond part from time.Nanosecond and then adding the results together.
We now format the whole part and the decimal part separately. Since the whole part is by definition, we need not covert it to a float, hence the whole part can simply be formatted as an integer. The and since by definition of the `Time.Nanoseconds()`, the return value is between 0-999999999, only this part needs to be formatted separately. We then combine whole + decimals[1:] to form the final result. This allows us to correctly format the maximun timestamp that is allowed by Go.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay on this. I was quite busy for personal reasons for a while. Looks good overall, just some minor details like variable naming and some comments would be nice.
used to marshal times. Improved variable naming and fixed typos.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay, thanks for submitting this. LGTM.
Fixed #199
The original issue was caused by the fact that if we use a very large
unix timestamp. The resulting value from
Time.UnixNano()
overflows a int64, as documented here: https://pkg.go.dev/time#Time.UnixNano.
This patch works around the issue by treating the second part and
nanosecond part separately, taking the second part from
Time.Unix()
,and the nanosecond part from
Time.Nanosecond()
, formatting themseparately, and then combining the resulting strings.
This approach allows us to correctly marshal all go
time.Time
instances,whereas using
Time.Unix
won't give us enough precision, and eitherTime.UnixMicro
orTime.UnixNano
would overflow at some point foreven valid
time.Time
instances.The added benefit of this approach is that we no longer have to deal
with the added nanosecond delta that Go uses in order to achieve
monotonic time, so the result of marshaling
time.Unix(0, 123456)
willsimply be
0.123456
instead of0.123456 + small_delta
.