From 19dc2c205a0fc9c3a556a171f6c1fff3bcb21914 Mon Sep 17 00:00:00 2001 From: sigoden Date: Sat, 25 Apr 2026 17:59:44 +0800 Subject: [PATCH] fix: http range underflow (#690) --- src/utils.rs | 2 +- tests/range.rs | 22 ++++++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/utils.rs b/src/utils.rs index e9993fd..c22e494 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -121,7 +121,7 @@ pub fn parse_range(range: &str, size: u64) -> Option> { result.push((start, size - 1)); } else { let end = end.parse::().ok()?; - if end < size { + if end < size && start <= end { result.push((start, end)); } else { return None; diff --git a/tests/range.rs b/tests/range.rs index 209ed1e..5e0e113 100644 --- a/tests/range.rs +++ b/tests/range.rs @@ -104,3 +104,25 @@ fn get_file_multipart_range_invalid(server: TestServer) -> Result<(), Error> { assert_eq!(resp.headers().get("content-length").unwrap(), "0"); Ok(()) } + +#[rstest] +fn get_file_range_reversed(server: TestServer) -> Result<(), Error> { + let resp = fetch!(b"GET", format!("{}index.html", server.url())) + .header("range", HeaderValue::from_static("bytes=10-1")) + .send()?; + assert_eq!(resp.status(), 416); + assert_eq!(resp.headers().get("content-range").unwrap(), "bytes */18"); + assert_eq!(resp.headers().get("accept-ranges").unwrap(), "bytes"); + Ok(()) +} + +#[rstest] +fn get_file_multipart_range_reversed(server: TestServer) -> Result<(), Error> { + let resp = fetch!(b"GET", format!("{}index.html", server.url())) + .header("range", HeaderValue::from_static("bytes=10-1,20-2")) + .send()?; + assert_eq!(resp.status(), 416); + assert_eq!(resp.headers().get("content-range").unwrap(), "bytes */18"); + assert_eq!(resp.headers().get("accept-ranges").unwrap(), "bytes"); + Ok(()) +}