diff options
-rw-r--r-- | Cargo.lock | 11 | ||||
-rw-r--r-- | ports/glutin/Cargo.toml | 1 | ||||
-rw-r--r-- | ports/glutin/browser.rs | 30 |
3 files changed, 39 insertions, 3 deletions
diff --git a/Cargo.lock b/Cargo.lock index 06faf8677f9..b9994f70cee 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4799,6 +4799,7 @@ dependencies = [ "osmesa-sys", "rust-webvr", "servo-media", + "shellwords", "sig", "tinyfiledialogs", "webxr", @@ -5190,6 +5191,16 @@ dependencies = [ ] [[package]] +name = "shellwords" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "685f0e9b0efe23d26e60a780d8dcd3ac95e90975814de9bc6f48e5d609b5d0f5" +dependencies = [ + "lazy_static", + "regex", +] + +[[package]] name = "shlex" version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/ports/glutin/Cargo.toml b/ports/glutin/Cargo.toml index ab5e1c71aab..3e8cb38f560 100644 --- a/ports/glutin/Cargo.toml +++ b/ports/glutin/Cargo.toml @@ -62,6 +62,7 @@ libc = "0.2" log = "0.4" rust-webvr = { version = "0.16", features = ["glwindow"] } servo-media = {git = "https://github.com/servo/media"} +shellwords = "1.0.0" tinyfiledialogs = "3.0" webxr-api = { git = "https://github.com/servo/webxr", features = ["ipc"] } webxr = { git = "https://github.com/servo/webxr", features = ["ipc", "glwindow", "headless"] } diff --git a/ports/glutin/browser.rs b/ports/glutin/browser.rs index 976026a483b..f5da82936dd 100644 --- a/ports/glutin/browser.rs +++ b/ports/glutin/browser.rs @@ -116,7 +116,7 @@ where String::from("") }; let title = "URL or search query"; - let input = tinyfiledialogs::input_box(title, title, &url); + let input = tinyfiledialogs::input_box(title, title, &tiny_dialog_escape(&url)); if let Some(input) = input { if let Some(url) = sanitize_url(&input) { if let Some(id) = self.browser_id { @@ -306,7 +306,7 @@ where .spawn(move || { tinyfiledialogs::message_box_ok( "Alert!", - &message, + &tiny_dialog_escape(&message), MessageBoxIcon::Warning, ); }) @@ -503,7 +503,7 @@ fn get_selected_files(patterns: Vec<FilterPattern>, multiple_files: bool) -> Opt let mut filters = vec![]; for p in patterns { let s = "*.".to_string() + &p.0; - filters.push(s) + filters.push(tiny_dialog_escape(&s)) } let filter_ref = &(filters.iter().map(|s| s.as_str()).collect::<Vec<&str>>()[..]); let filter_opt = if filters.len() > 0 { @@ -540,3 +540,27 @@ fn sanitize_url(request: &str) -> Option<ServoUrl> { ServoUrl::parse(&url).ok() }) } + +// This is a mitigation for #25498, not a verified solution. +// There may be codepaths in tinyfiledialog.c that this is +// inadquate against, as it passes the string via shell to +// different programs depending on what the user has installed. +#[cfg(target_os = "linux")] +fn tiny_dialog_escape(raw: &str) -> String { + let s:String = raw.chars() + .filter_map(|c| match c { + '\n' => Some('\n'), + '\0' ..= '\x1f' => None, + '<' => Some('\u{FF1C}'), + '>' => Some('\u{FF1E}'), + '&' => Some('\u{FF06}'), + _ => Some(c) + }) + .collect(); + return shellwords::escape(&s); +} + +#[cfg(not(target_os = "linux"))] +fn tiny_dialog_escape(raw: &str) -> String { + raw.to_string() +} |