aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock11
-rw-r--r--ports/glutin/Cargo.toml1
-rw-r--r--ports/glutin/browser.rs30
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()
+}