tinyfiledialogs mitigation

This commit is contained in:
Patrick Shaughnessy 2020-01-14 18:57:04 -05:00
parent 92fe8a66cc
commit de76597d33
3 changed files with 39 additions and 3 deletions

11
Cargo.lock generated
View file

@ -4799,6 +4799,7 @@ dependencies = [
"osmesa-sys",
"rust-webvr",
"servo-media",
"shellwords",
"sig",
"tinyfiledialogs",
"webxr",
@ -5189,6 +5190,16 @@ dependencies = [
"libc",
]
[[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"

View file

@ -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"] }

View file

@ -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()
}