mirror of
https://github.com/tokio-rs/axum.git
synced 2026-08-25 00:00:23 +02:00
47 lines
1.2 KiB
Rust
47 lines
1.2 KiB
Rust
use std::fmt::{self, Write};
|
|
|
|
/// A wrapper type that escapes backslashes and double quotes when formatted,
|
|
/// for safe inclusion in Content-Disposition header quoted-strings.
|
|
///
|
|
/// This prevents Content-Disposition header parameter injection
|
|
/// (similar to CVE-2023-29401).
|
|
pub(crate) struct EscapedFilename<'a>(pub &'a str);
|
|
|
|
impl fmt::Display for EscapedFilename<'_> {
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
for c in self.0.chars() {
|
|
if c == '\\' || c == '"' {
|
|
f.write_char('\\')?;
|
|
}
|
|
f.write_char(c)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn no_special_characters() {
|
|
assert_eq!(EscapedFilename("report.pdf").to_string(), "report.pdf");
|
|
}
|
|
|
|
#[test]
|
|
fn escapes_double_quotes() {
|
|
assert_eq!(
|
|
EscapedFilename("evil\"; filename*=UTF-8''pwned.txt; x=\"").to_string(),
|
|
"evil\\\"; filename*=UTF-8''pwned.txt; x=\\\"",
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn escapes_backslashes() {
|
|
assert_eq!(
|
|
EscapedFilename("file\\name.txt").to_string(),
|
|
"file\\\\name.txt",
|
|
);
|
|
}
|
|
}
|