Reject signed numbers in Content-Range parsing

Found while testing crates/fetch/src/lib.rs:465 (parse_content_range)

Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
NetterSilver
2026-10-28 09:09:41 +00:00
co-authored by Claude Haiku 5.5
parent 59a5d00c60
commit 73f0d25405
2 changed files with 15 additions and 2 deletions
+11 -2
View File
@@ -466,16 +466,25 @@ fn parse_content_range(v: &str) -> Option<(u64, Option<u64>)> {
let v = v.trim().strip_prefix("bytes")?.trim();
let (range, total) = v.split_once('/')?;
let (a, b) = range.split_once('-')?;
let (a, b) = (a.trim().parse::<u64>().ok()?, b.trim().parse::<u64>().ok()?);
let (a, b) = (digits(a)?, digits(b)?);
if b < a {
return None;
}
let total = match total.trim() {
"*" => None,
t => Some(t.parse::<u64>().ok()?),
t => Some(digits(t)?),
};
Some((a, total))
}
/// A non-empty run of ASCII digits as a `u64` (no sign, unlike `str::parse`).
fn digits(s: &str) -> Option<u64> {
let s = s.trim();
if s.is_empty() || !s.bytes().all(|b| b.is_ascii_digit()) {
return None;
}
s.parse().ok()
}
#[cfg(test)]
mod tests;
+4
View File
@@ -335,6 +335,10 @@ fn content_ranges() {
assert_eq!(parse_content_range("bytes 0-0/*"), Some((0, None)));
assert_eq!(parse_content_range("bytes 9-1/300"), None);
assert_eq!(parse_content_range("items 1-2/3"), None);
assert_eq!(parse_content_range("bytes +100-+299/+300"), None);
assert_eq!(parse_content_range("bytes 100-+299/300"), None);
assert_eq!(parse_content_range("bytes 100-299/+300"), None);
assert_eq!(parse_content_range("bytes 1-/3"), None);
}
/// A bearer token goes only to https, only to the host the download began at, and only when there is one.