Fix recursive call leading to stack overflow when tracing level filter is TRACE (#3312)

This commit is contained in:
Denis
2025-04-24 13:03:50 +02:00
committed by GitHub
parent 1599569df2
commit 6bf1fcbb29
3 changed files with 45 additions and 3 deletions
+42 -2
View File
@@ -243,12 +243,13 @@ impl MultipartError {
/// Get the response body text used for this rejection.
pub fn body_text(&self) -> String {
let body = self.source.to_string();
axum_core::__log_rejection!(
rejection_type = Self,
body_text = self.body_text(),
body_text = body,
status = self.status(),
);
self.source.to_string()
body
}
/// Get the status code used for this rejection.
@@ -398,4 +399,43 @@ mod tests {
let res = client.post("/").multipart(form).await;
assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);
}
#[tokio::test]
#[cfg(feature = "tracing")]
async fn body_too_large_with_tracing() {
const BYTES: &[u8] = "<!doctype html><title>🦀</title>".as_bytes();
async fn handle(mut multipart: Multipart) -> impl IntoResponse {
let result: Result<(), MultipartError> = async {
while let Some(field) = multipart.next_field().await? {
field.bytes().await?;
}
Ok(())
}
.await;
let subscriber = tracing_subscriber::FmtSubscriber::builder()
.with_max_level(tracing::level_filters::LevelFilter::TRACE)
.with_writer(std::io::sink)
.finish();
let guard = tracing::subscriber::set_default(subscriber);
let response = result.into_response();
drop(guard);
response
}
let app = Router::new()
.route("/", post(handle))
.layer(DefaultBodyLimit::max(BYTES.len() - 1));
let client = TestClient::new(app);
let form =
reqwest::multipart::Form::new().part("file", reqwest::multipart::Part::bytes(BYTES));
let res = client.post("/").multipart(form).await;
assert_eq!(res.status(), StatusCode::PAYLOAD_TOO_LARGE);
}
}