mirror of
https://github.com/ducaale/xh.git
synced 2025-05-05 15:32:50 +00:00
use sanitize-filename crate to make filenames safe
Sanitizes filenames by removing or replacing potentially problematic characters Makes filenames safe for cross-platform use Prevents directory traversal attacks (e.g., "../../../")
This commit is contained in:
parent
a60a52453a
commit
31c515e403
10
Cargo.lock
generated
10
Cargo.lock
generated
@ -1841,6 +1841,15 @@ dependencies = [
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sanitize-filename"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc984f4f9ceb736a7bb755c3e3bd17dc56370af2600c9780dcc48c66453da34d"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.27"
|
||||
@ -2823,6 +2832,7 @@ dependencies = [
|
||||
"rpassword",
|
||||
"rustls",
|
||||
"ruzstd",
|
||||
"sanitize-filename",
|
||||
"serde",
|
||||
"serde-transcode",
|
||||
"serde_json",
|
||||
|
@ -61,6 +61,7 @@ rustls = { version = "0.23.25", optional = true, default-features = false, featu
|
||||
tracing = { version = "0.1.41", default-features = false, features = ["log"] }
|
||||
reqwest_cookie_store = { version = "0.8.0", features = ["serde"] }
|
||||
percent-encoding = "2.3.1"
|
||||
sanitize-filename = "0.6.0"
|
||||
|
||||
[dependencies.reqwest]
|
||||
version = "0.12.3"
|
||||
|
@ -41,7 +41,7 @@ fn parse_regular_filename(part: &str) -> Option<String> {
|
||||
// It's not a standard practice
|
||||
// It rarely occurs in real-world scenarios
|
||||
// When filenames contain special characters, they should use the filename* parameter
|
||||
let filename = if filename.starts_with('"') && filename.ends_with('"') {
|
||||
let filename = if filename.starts_with('"') && filename.ends_with('"') && filename.len() >= 2 {
|
||||
&filename[1..(filename.len() - 1)]
|
||||
} else {
|
||||
filename
|
||||
|
@ -52,7 +52,7 @@ fn get_file_name(response: &Response, orig_url: &reqwest::Url) -> String {
|
||||
.or_else(|| from_url(orig_url))
|
||||
.unwrap_or_else(|| "index".to_string());
|
||||
|
||||
let filename = filename.split(std::path::is_separator).next_back().unwrap();
|
||||
let filename = sanitize_filename::sanitize(&filename);
|
||||
|
||||
let mut filename = filename.trim().trim_start_matches('.').to_string();
|
||||
|
||||
|
@ -229,7 +229,10 @@ fn download_filename_with_directory_traversal() {
|
||||
.current_dir(&dir)
|
||||
.assert()
|
||||
.success();
|
||||
assert_eq!(fs::read_to_string(dir.path().join("bar")).unwrap(), "file");
|
||||
assert_eq!(
|
||||
fs::read_to_string(dir.path().join("foobazbar")).unwrap(),
|
||||
"file"
|
||||
);
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
@ -251,7 +254,10 @@ fn download_filename_with_windows_directory_traversal() {
|
||||
.current_dir(&dir)
|
||||
.assert()
|
||||
.success();
|
||||
assert_eq!(fs::read_to_string(dir.path().join("bar")).unwrap(), "file");
|
||||
assert_eq!(
|
||||
fs::read_to_string(dir.path().join("foobazbar")).unwrap(),
|
||||
"file"
|
||||
);
|
||||
}
|
||||
|
||||
// TODO: test implicit download filenames
|
||||
|
Loading…
x
Reference in New Issue
Block a user