fix: avoid panic in duration parser on out-of-range values - #67
Merged
badboy merged 1 commit intoAug 19, 2026
Merged
Conversation
…ion values The duration parser reads each numeric component with take_digits, which parsed the collected ASCII digits into a u32 with .expect(). A component whose value exceeds u32::MAX (e.g. "P99999999999Y") made the u32 conversion fail and the .expect() panic, so iso8601::duration() could panic on untrusted input. The date/time/datetime parsers use fixed-width digit helpers and are unaffected, which is why the existing fuzz targets did not surface this. take_digits now returns a nom parser error when the number does not fit into a u32, so the parse fails gracefully. Values up to u32::MAX still parse. Adds a regression test.
badboy
approved these changes
Aug 19, 2026
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.
While parsing untrusted input I hit a panic in
iso8601::duration().Any duration whose numeric component is larger than
u32::MAXcrashes theparser:
Cause
Every duration component is read by
take_digits, which collects a run ofASCII digits and then converts it with
.parse().expect(...):take_digitsaccepts an unbounded number of digits, so a value that does notfit into a
u32makes the conversion returnErrand the.expect()panics.Because the panic is a failed
Result::expect(not an arithmetic overflow), itfires in both debug and release builds.
Only the duration grammar uses the unbounded
take_digits; the date, time anddatetime parsers use the fixed-width
take_n_digitshelper (max 4 digits), sothey are not affected. That is also why the existing
parse_datesfuzz targetnever surfaced this — it exercises
date/time/datetimebut notduration.Fix
take_digitsnow returns a normal parser error when the digits do not fit intoa
u32, so the parse fails gracefully instead of panicking. Values up tou32::MAXstill parse unchanged. Added a regression test covering eachduration component and confirming
u32::MAXstill parses.cargo test,cargo fmt --checkandcargo clippyall pass.