diff --git a/testing/geckodriver/Cargo.lock b/testing/geckodriver/Cargo.lock index eca3fedbbfc6..4a657d0dbdab 100644 --- a/testing/geckodriver/Cargo.lock +++ b/testing/geckodriver/Cargo.lock @@ -8,7 +8,7 @@ dependencies = [ "lazy_static 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)", "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", "mozprofile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)", - "mozrunner 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", + "mozrunner 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "mozversion 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "regex 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-serialize 0.3.22 (registry+https://github.com/rust-lang/crates.io-index)", @@ -296,7 +296,7 @@ dependencies = [ [[package]] name = "mozrunner" -version = "0.4.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -718,7 +718,7 @@ dependencies = [ "checksum mime 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d69889cdc6336ed56b174514ce876c4c3dc564cc23dd872e7bca589bb2a36c8" "checksum miniz-sys 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "28eaee17666671fa872e567547e8428e83308ebe5808cdf6a0e28397dbe2c726" "checksum mozprofile 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1a17b8bbde1dc0fbf1c8b073192d7c6f89baa932173ece7c1447de5e9cc7cd7e" -"checksum mozrunner 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a568168329fc285ad6d04dfbe058ea20ff842f4301fe9205c6cbd4ed3be85378" +"checksum mozrunner 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "68e6a21ef32a737399a34d9a89640b350d8b47ef03457225c0c223842cf2311f" "checksum mozversion 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9fb3a40135553611560d3eb4a49479beaf0c91c5a93f723338c5b0edddf08f26" "checksum msdos_time 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "65ba9d75bcea84e07812618fedf284a64776c2f2ea0cad6bca7f69739695a958" "checksum num 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)" = "98b15ba84e910ea7a1973bccd3df7b31ae282bf9d8bd2897779950c9b8303d40" diff --git a/testing/geckodriver/Cargo.toml b/testing/geckodriver/Cargo.toml index 70eac9ccab6e..5fb2c6795205 100644 --- a/testing/geckodriver/Cargo.toml +++ b/testing/geckodriver/Cargo.toml @@ -17,9 +17,9 @@ clap = {version = "^2.19", default-features = false, features = ["suggestions", hyper = "0.10" lazy_static = "0.1" log = "0.3" -mozprofile = "0.3" -mozrunner = "0.4" -mozversion = "0.1" +mozprofile = "0.3.0" +mozrunner = "0.4.1" +mozversion = "0.1.2" regex = "0.2" rustc-serialize = "0.3" slog = "1" diff --git a/third_party/rust/mozrunner/.cargo-checksum.json b/third_party/rust/mozrunner/.cargo-checksum.json index 474f0cd12936..7db647546a98 100644 --- a/third_party/rust/mozrunner/.cargo-checksum.json +++ b/third_party/rust/mozrunner/.cargo-checksum.json @@ -1 +1 @@ -{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"25af4086ef96f79688c6888d88df053fc04d0ff8e3c4353a6aea91605afc58ef","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","src/bin/firefox-default-path.rs":"21f1aa96a4ffb368a4266e294bc4b1b17ff8229f2418af6679783f6d9c0280df","src/lib.rs":"3ed528f2069e810adb6f2ea0b248c4542de95f1cc305154f440877d4ee6d550c","src/runner.rs":"ed095febfb54c87648fecb4818e7726702f6e46053119ffd9316c664b7e93b3e"},"package":"a568168329fc285ad6d04dfbe058ea20ff842f4301fe9205c6cbd4ed3be85378"} \ No newline at end of file +{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"c9da3b2127ac20e0f3b7f87d7ee3a08a103f7893e92ee2835a3247af0389371f","LICENSE":"fab3dd6bdab226f1c08630b1dd917e11fcb4ec5e1e020e2c16f83a0a13863e85","src/bin/firefox-default-path.rs":"21f1aa96a4ffb368a4266e294bc4b1b17ff8229f2418af6679783f6d9c0280df","src/lib.rs":"26ea358c4bc1d45eb3b5ebc702b1a6bffdf5642acab9bbeffddb5be55ddb1b07","src/runner.rs":"ce33d910a0d63bb3673e159bc52f1fb4dafd9746415592f5f2bf792691f2adb2"},"package":"68e6a21ef32a737399a34d9a89640b350d8b47ef03457225c0c223842cf2311f"} \ No newline at end of file diff --git a/third_party/rust/mozrunner/Cargo.toml b/third_party/rust/mozrunner/Cargo.toml index 400acc7ff571..6f7cc7322ea6 100644 --- a/third_party/rust/mozrunner/Cargo.toml +++ b/third_party/rust/mozrunner/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "mozrunner" -version = "0.4.0" +version = "0.4.1" authors = ["Mozilla Tools and Automation "] description = "Library for starting Firefox binaries." repository = "https://github.com/jgraham/rust_mozrunner" diff --git a/third_party/rust/mozrunner/src/lib.rs b/third_party/rust/mozrunner/src/lib.rs index f31c873eb27c..95806f084aaa 100644 --- a/third_party/rust/mozrunner/src/lib.rs +++ b/third_party/rust/mozrunner/src/lib.rs @@ -1,4 +1,4 @@ -extern crate log; +#[macro_use] extern crate log; extern crate mozprofile; #[cfg(target_os = "windows")] extern crate winreg; diff --git a/third_party/rust/mozrunner/src/runner.rs b/third_party/rust/mozrunner/src/runner.rs index d0cd22381fed..e5792a4704df 100644 --- a/third_party/rust/mozrunner/src/runner.rs +++ b/third_party/rust/mozrunner/src/runner.rs @@ -1,5 +1,6 @@ use mozprofile::prefreader::PrefReaderError; use mozprofile::profile::Profile; +use std::ascii::AsciiExt; use std::convert::From; use std::env; use std::error::Error; @@ -96,6 +97,8 @@ impl Runner for FirefoxRunner { let mut cmd = Command::new(&self.binary); self.build_command(&mut cmd); + debug!("Command {:?}", cmd); + let prefs = try!(self.profile.user_prefs()); try!(prefs.write()); @@ -112,9 +115,12 @@ impl Runner for FirefoxRunner { command .env("MOZ_NO_REMOTE", "1") .env("NO_EM_RESTART", "1") - .args(&self.args[..]) - .arg("-profile").arg(&self.profile.path) - .stdout(Stdio::inherit()) + .args(&self.args[..]); + + if !self.args.iter().any(|x| is_profile_arg(x)) { + command.arg("-profile").arg(&self.profile.path); + } + command.stdout(Stdio::inherit()) .stderr(Stdio::inherit()); } @@ -123,18 +129,69 @@ impl Runner for FirefoxRunner { } fn stop(&mut self) -> IoResult> { - match self.process.as_mut() { - Some(p) => { - try!(p.kill()); - let status = try!(p.wait()); - self.ret_code = Some(status); - }, - None => {} + if let Some(p) = self.process.as_mut() { + try!(p.kill()); + let status = try!(p.wait()); + self.ret_code = Some(status); }; Ok(self.ret_code) } } +fn parse_arg_name(arg: &str) -> Option<&str> { + let mut start = 0; + let mut end = 0; + + for (i, c) in arg.chars().enumerate() { + if i == 0 { + if !platform::arg_prefix_char(c) { + break; + } + } else if i == 1 { + if name_end_char(c) { + break; + } else if c != '-' { + start = i; + end = start + 1; + } else { + start = i + 1; + end = start; + } + } else { + end += 1; + if name_end_char(c) { + end -= 1; + break; + } + } + } + + if start > 0 && end > start { + Some(&arg[start..end]) + } else { + None + } +} + +fn name_end_char(c: char) -> bool { + c == ' ' || c == '=' +} + +/// Check if an argument string affects the Firefox profile +/// +/// Returns a boolean indicating whether a given string +/// contains one of the `-P`, `-Profile` or `-ProfileManager` +/// arguments, respecting the various platform-specific conventions. +pub fn is_profile_arg(arg: &str) -> bool { + if let Some(name) = parse_arg_name(arg) { + name.eq_ignore_ascii_case("profile") || + name.eq_ignore_ascii_case("p") || + name.eq_ignore_ascii_case("profilemanager") + } else { + false + } +} + fn find_binary(name: &str) -> Option { env::var("PATH") .ok() @@ -157,6 +214,10 @@ pub mod platform { pub fn firefox_default_path() -> Option { find_binary("firefox") } + + pub fn arg_prefix_char(c: char) -> bool { + c == '-' + } } #[cfg(target_os = "macos")] @@ -184,6 +245,10 @@ pub mod platform { } None } + + pub fn arg_prefix_char(c: char) -> bool { + c == '-' + } } #[cfg(target_os = "windows")] @@ -234,6 +299,10 @@ pub mod platform { } Ok(None) } + + pub fn arg_prefix_char(c: char) -> bool { + c == '/' || c == '-' + } } #[cfg(not(any(target_os = "linux", target_os = "macos", target_os = "windows")))] @@ -243,4 +312,65 @@ pub mod platform { pub fn firefox_default_path() -> Option { None } + + pub fn arg_prefix_char(c: char) -> bool { + c == '-' + } +} + +#[cfg(test)] +mod tests { + use super::{parse_arg_name, is_profile_arg}; + + fn parse(arg: &str, name: Option<&str>) { + let result = parse_arg_name(arg); + assert_eq!(result, name); + } + + #[test] + fn test_parse_arg_name() { + parse("-p", Some("p")); + parse("--p", Some("p")); + parse("--profile foo", Some("profile")); + parse("--profile", Some("profile")); + parse("--", None); + parse("", None); + parse("-=", None); + parse("--=", None); + parse("-- foo", None); + parse("foo", None); + parse("/ foo", None); + parse("/- foo", None); + parse("/=foo", None); + parse("foo", None); + parse("-profile", Some("profile")); + parse("-profile=foo", Some("profile")); + parse("-profile = foo", Some("profile")); + parse("-profile abc", Some("profile")); + } + + #[cfg(target_os = "windows")] + #[test] + fn test_parse_arg_name_windows() { + parse("/profile", Some("profile")); + } + + #[cfg(not(target_os = "windows"))] + #[test] + fn test_parse_arg_name_non_windows() { + parse("/profile", None); + } + + #[test] + fn test_is_profile_arg() { + assert!(is_profile_arg("--profile")); + assert!(is_profile_arg("-p")); + assert!(is_profile_arg("-PROFILEMANAGER")); + assert!(is_profile_arg("-ProfileMANAGER")); + assert!(!is_profile_arg("-- profile")); + assert!(!is_profile_arg("-profiled")); + assert!(!is_profile_arg("-p1")); + assert!(is_profile_arg("-p test")); + assert!(is_profile_arg("-profile /foo")); + } }