Skip to content

Commit d5b43a3

Browse files
committed
Fix integer underflow in try_range_response for empty files
1 parent b1ef454 commit d5b43a3

File tree

1 file changed

+61
-0
lines changed

1 file changed

+61
-0
lines changed

axum-extra/src/response/file_stream.rs

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,10 @@ where
191191
let metadata = file.metadata().await?;
192192
let total_size = metadata.len();
193193

194+
if total_size == 0 {
195+
return Ok((StatusCode::RANGE_NOT_SATISFIABLE, "Range Not Satisfiable").into_response());
196+
}
197+
194198
if end == 0 {
195199
end = total_size - 1;
196200
}
@@ -596,4 +600,61 @@ mod tests {
596600
}
597601
Some((start, end))
598602
}
603+
604+
#[tokio::test]
605+
async fn response_range_empty_file() -> Result<(), Box<dyn std::error::Error>> {
606+
struct TempFile(&'static str);
607+
608+
impl Drop for TempFile {
609+
fn drop(&mut self) {
610+
let _ = std::fs::remove_file(self.0);
611+
}
612+
}
613+
614+
let filename = "test_empty_file.txt";
615+
std::fs::write(filename, &[]).unwrap();
616+
let _cleanup = TempFile(filename);
617+
618+
let app = Router::new().route(
619+
"/range_empty",
620+
get(move |headers: HeaderMap| async move {
621+
let range_header = headers
622+
.get(header::RANGE)
623+
.and_then(|value| value.to_str().ok());
624+
625+
let (start, end) = if let Some(range) = range_header {
626+
if let Some(range) = parse_range_header(range) {
627+
range
628+
} else {
629+
return (StatusCode::RANGE_NOT_SATISFIABLE, "Invalid Range")
630+
.into_response();
631+
}
632+
} else {
633+
(0, 0)
634+
};
635+
636+
FileStream::<ReaderStream<File>>::try_range_response(
637+
Path::new("test_empty_file.txt"),
638+
start,
639+
end,
640+
)
641+
.await
642+
.unwrap_or_else(|_| StatusCode::INTERNAL_SERVER_ERROR.into_response())
643+
}),
644+
);
645+
646+
let response = app
647+
.oneshot(
648+
Request::builder()
649+
.uri("/range_empty")
650+
.header(header::RANGE, "bytes=0-")
651+
.body(Body::empty())
652+
.unwrap(),
653+
)
654+
.await
655+
.unwrap();
656+
657+
assert_eq!(response.status(), StatusCode::RANGE_NOT_SATISFIABLE);
658+
Ok(())
659+
}
599660
}

0 commit comments

Comments
 (0)