Fix path traversal, encoding, and edge case bugs

This commit is contained in:
2026-03-07 20:49:10 +02:00
parent 9e1562c4c4
commit 150d483fbe
14 changed files with 207 additions and 106 deletions

View File

@@ -883,20 +883,25 @@ fn download_image_url(url: &str) -> Option<std::path::PathBuf> {
let temp_dir = std::env::temp_dir().join("pixstrip-downloads");
std::fs::create_dir_all(&temp_dir).ok()?;
// Extract filename from URL
// Extract and sanitize filename from URL to prevent path traversal
let url_path = url.split('?').next().unwrap_or(url);
let filename = url_path
let raw_name = url_path
.rsplit('/')
.next()
.unwrap_or("downloaded.jpg")
.to_string();
.unwrap_or("downloaded.jpg");
let sanitized = std::path::Path::new(raw_name)
.file_name()
.and_then(|f| f.to_str())
.unwrap_or("downloaded.jpg");
let filename = if sanitized.is_empty() { "downloaded.jpg" } else { sanitized };
let dest = temp_dir.join(&filename);
let dest = temp_dir.join(filename);
// Use GIO for the download (synchronous, runs in background thread)
let gfile = gtk::gio::File::for_uri(url);
let stream = gfile.read(gtk::gio::Cancellable::NONE).ok()?;
const MAX_DOWNLOAD_BYTES: usize = 100 * 1024 * 1024; // 100 MB
let mut buf = Vec::new();
loop {
let bytes = stream.read_bytes(8192, gtk::gio::Cancellable::NONE).ok()?;
@@ -904,6 +909,9 @@ fn download_image_url(url: &str) -> Option<std::path::PathBuf> {
break;
}
buf.extend_from_slice(&bytes);
if buf.len() > MAX_DOWNLOAD_BYTES {
return None;
}
}
if buf.is_empty() {