Widen the postgres interval month arithmetic - #5204
Draft
LucaCappelletti94 wants to merge 1 commit into
Draft
Conversation
LucaCappelletti94
force-pushed
the
fuzz-pg-interval-month-overflow
branch
from
September 5, 2026 07:14
43b1d39 to
30313c4
Compare
LucaCappelletti94
force-pushed
the
fuzz-pg-interval-month-overflow
branch
from
September 5, 2026 07:42
30313c4 to
58911ce
Compare
Mingun
reviewed
Sep 5, 2026
| Ok(Duration::days(days as i64) + Duration::microseconds(interval.microseconds)) | ||
| // widened, since any `i32` month and day pair fits `i64` days and chrono | ||
| let days = | ||
| i64::from(interval.months) * i64::from(DAYS_PER_MONTH) + i64::from(interval.days); |
Contributor
There was a problem hiding this comment.
Just change the DAYS_PER_MONTH to be i64.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
FromSql<Interval, Pg> for chrono::Durationcomputesinterval.months * DAYS_PER_MONTH + interval.daysini32, and all three fields arrive off the wire, so a well formed 16 byte interval is enough to overflow it. With debug assertions the conversion panics, and without them it wraps and the caller gets a plausible looking duration that is wrong, often with the opposite sign, where one month together withi32::MAXdays reads as-185542584681600seconds where the true value is185542589692800.It does not take an absurd month count either, one month is already enough once the day count is large. This is the arithmetic one line past the length check fixed in #5194, which does not touch it.
Counting the days in
i64removes the overflow without narrowing what is accepted, as the widest interval is about 66678745079 days, whilechrono::Durationreaches 106751991167.This came out of a fuzzer I am writing for diesel's deserialization code.