Skip to content

Commit

Permalink
actix-files: Properly handle newlines in file names (#3235)
Browse files Browse the repository at this point in the history
  • Loading branch information
svenstaro committed Jan 6, 2024
1 parent 561cc44 commit febba78
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
1 change: 1 addition & 0 deletions actix-files/CHANGES.md
Expand Up @@ -3,6 +3,7 @@
## Unreleased

- Minimum supported Rust version (MSRV) is now 1.68 due to transitive `time` dependency.
- Properly handle newlines in filenames. [#3235]

## 0.6.3

Expand Down
22 changes: 21 additions & 1 deletion actix-files/src/lib.rs
Expand Up @@ -568,6 +568,26 @@ mod tests {
assert_eq!(bytes, data);
}

#[actix_rt::test]
async fn test_static_files_with_newlines() {
// Create the file we want to test against ad-hoc. We can't check it in as otherwise
// Windows can't even checkout this repository.
let tmpdir = tempfile::tempdir().unwrap();
let file_with_newlines = tmpdir.path().join("test\nnewline.text");
fs::write(&file_with_newlines, "Look at my newlines").unwrap();
let srv = test::init_service(
App::new().service(Files::new("", tmpdir.path()).index_file("Cargo.toml")),
)
.await;
let request = TestRequest::get().uri("/test%0Anewline.text").to_request();
let response = test::call_service(&srv, request).await;
assert_eq!(response.status(), StatusCode::OK);

let bytes = test::read_body(response).await;
let data = web::Bytes::from(fs::read(file_with_newlines).unwrap());
assert_eq!(bytes, data);
}

#[actix_rt::test]
async fn test_files_not_allowed() {
let srv = test::init_service(App::new().service(Files::new("/", "."))).await;
Expand Down Expand Up @@ -842,7 +862,7 @@ mod tests {
async fn test_percent_encoding_2() {
let tmpdir = tempfile::tempdir().unwrap();
let filename = match cfg!(unix) {
true => "ض:?#[]{}<>()@!$&'`|*+,;= %20.test",
true => "ض:?#[]{}<>()@!$&'`|*+,;= %20\n.test",
false => "ض#[]{}()@!$&'`+,;= %20.test",
};
let filename_encoded = filename
Expand Down
7 changes: 4 additions & 3 deletions actix-files/src/named.rs
Expand Up @@ -24,7 +24,6 @@ use bitflags::bitflags;
use derive_more::{Deref, DerefMut};
use futures_core::future::LocalBoxFuture;
use mime::Mime;
use mime_guess::from_path;

use crate::{encoding::equiv_utf8_text, range::HttpRange};

Expand Down Expand Up @@ -128,7 +127,7 @@ impl NamedFile {
}
};

let ct = from_path(&path).first_or_octet_stream();
let ct = mime_guess::from_path(&path).first_or_octet_stream();

let disposition = match ct.type_() {
mime::IMAGE | mime::TEXT | mime::AUDIO | mime::VIDEO => DispositionType::Inline,
Expand All @@ -140,7 +139,9 @@ impl NamedFile {
_ => DispositionType::Attachment,
};

let mut parameters = vec![DispositionParam::Filename(String::from(filename.as_ref()))];
// Replace newlines in filenames which could occur on some filesystems.
let filename_s = filename.replace('\n', "%0A");
let mut parameters = vec![DispositionParam::Filename(filename_s)];

if !filename.is_ascii() {
parameters.push(DispositionParam::FilenameExt(ExtendedValue {
Expand Down

0 comments on commit febba78

Please sign in to comment.