diff --git a/src/patch/parse.rs b/src/patch/parse.rs index 0191542..793ae31 100644 --- a/src/patch/parse.rs +++ b/src/patch/parse.rs @@ -273,7 +273,7 @@ fn hunk_header(input: &T) -> Result<(HunkRange, HunkRange, Opt } fn range(s: &T) -> Result { - let (start, len) = if let Some((start, len)) = s.split_at_exclusive(",") { + let (start, len): (usize, usize) = if let Some((start, len)) = s.split_at_exclusive(",") { ( start.parse().ok_or(ParsePatchErrorKind::InvalidRange)?, len.parse().ok_or(ParsePatchErrorKind::InvalidRange)?, @@ -282,6 +282,11 @@ fn range(s: &T) -> Result { (s.parse().ok_or(ParsePatchErrorKind::InvalidRange)?, 1) }; + // reject ranges that overflow + start + .checked_add(len) + .ok_or(ParsePatchErrorKind::InvalidRange)?; + Ok(HunkRange::new(start, len)) } diff --git a/src/patch/tests.rs b/src/patch/tests.rs index 7adc0a8..9efa79a 100644 --- a/src/patch/tests.rs +++ b/src/patch/tests.rs @@ -638,6 +638,24 @@ fn non_utf8_escaped_filename_returns_error_on_str_parse() { ); } +#[test] +fn hunk_range_overflow() { + let s = format!( + "\ +--- a/file.txt ++++ b/file.txt +@@ -{},1 +1 @@ +-old ++new +", + usize::MAX, + ); + assert_eq!( + crate::Patch::from_str(&s).unwrap_err().kind, + ParsePatchErrorKind::InvalidRange, + ); +} + mod error_display { use alloc::string::ToString;