axum-extra 0.12.6

Extra utilities for axum
Documentation
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",
        );
    }
}