Skip to content

Commit 329d29b

Browse files
authored
Merge branch 'trunk' into pinned-browser-updates
2 parents 4a5236f + ab453da commit 329d29b

6 files changed

Lines changed: 112 additions & 162 deletions

File tree

rust/src/config.rs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
// under the License.
1717

1818
use crate::config::OS::{LINUX, MACOS, WINDOWS};
19-
use crate::shell::run_shell_command_by_os;
19+
use crate::shell::run_shell_command;
2020
use crate::{
21-
ARCH_ARM7L, Command, ENV_PROCESSOR_ARCHITECTURE, REQUEST_TIMEOUT_SEC, UNAME_COMMAND,
22-
default_cache_folder, format_one_arg, path_to_string,
21+
ARCH_ARM7L, Command, ENV_PROCESSOR_ARCHITECTURE, REQUEST_TIMEOUT_SEC, default_cache_folder,
22+
path_to_string,
2323
};
2424
use crate::{ARCH_ARM64, ARCH_X64, ARCH_X86, TTL_SEC};
2525
use anyhow::Error;
@@ -46,6 +46,7 @@ pub const VERSION_PREFIX: &str = "-version";
4646
pub const PATH_PREFIX: &str = "-path";
4747
pub const MIRROR_PREFIX: &str = "-mirror-url";
4848
pub const CACHE_PATH_KEY: &str = "cache-path";
49+
const UNAME_COMMAND: &str = "uname";
4950

5051
pub struct ManagerConfig {
5152
pub cache_path: String,
@@ -91,16 +92,16 @@ impl ManagerConfig {
9192
ARCH_X64.to_string()
9293
}
9394
} else {
94-
let uname_a_command = Command::new_single(format_one_arg(UNAME_COMMAND, "a"));
95-
if run_shell_command_by_os(self_os, uname_a_command)
95+
let uname_a_command = Command::new(UNAME_COMMAND, vec![String::from("-a")]);
96+
if run_shell_command(uname_a_command)
9697
.unwrap_or_default()
9798
.to_ascii_lowercase()
9899
.contains(ARCH_ARM64)
99100
{
100101
ARCH_ARM64.to_string()
101102
} else {
102-
let uname_m_command = Command::new_single(format_one_arg(UNAME_COMMAND, "m"));
103-
run_shell_command_by_os(self_os, uname_m_command).unwrap_or_default()
103+
let uname_m_command = Command::new(UNAME_COMMAND, vec![String::from("-m")]);
104+
run_shell_command(uname_m_command).unwrap_or_default()
104105
}
105106
};
106107

rust/src/files.rs

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@
1717

1818
use crate::config::OS;
1919
use crate::config::OS::WINDOWS;
20-
use crate::{
21-
CP_VOLUME_COMMAND, Command, HDIUTIL_ATTACH_COMMAND, HDIUTIL_DETACH_COMMAND, Logger, MACOS,
22-
MSIEXEC_INSTALL_COMMAND, format_one_arg, format_three_args, run_shell_command_by_os,
23-
};
20+
use crate::{Command, Logger, MACOS, format_one_arg, run_shell_command};
2421
use anyhow::Error;
2522
use anyhow::anyhow;
2623
use apple_flat_package::PkgReader;
@@ -64,6 +61,7 @@ const MSI: &str = "msi";
6461
const XZ: &str = "xz";
6562
const SEVEN_ZIP_HEADER: &[u8; 6] = b"7z\xBC\xAF\x27\x1C";
6663
const UNCOMPRESS_MACOS_ERR_MSG: &str = "{} files are only supported in macOS";
64+
const HDIUTIL_COMMAND: &str = "hdiutil";
6765

6866
#[derive(Hash, Eq, PartialEq, Debug)]
6967
pub struct BrowserPath {
@@ -150,7 +148,7 @@ pub fn uncompress(
150148
} else if extension.eq_ignore_ascii_case(PKG) {
151149
uncompress_pkg(compressed_file, target, log)?
152150
} else if extension.eq_ignore_ascii_case(DMG) {
153-
uncompress_dmg(compressed_file, target, log, os, volume.unwrap_or_default())?
151+
uncompress_dmg(compressed_file, target, log, volume.unwrap_or_default())?
154152
} else if extension.eq_ignore_ascii_case(EXE) {
155153
uncompress_sfx(compressed_file, target, log)?
156154
} else if extension.eq_ignore_ascii_case(DEB) {
@@ -244,7 +242,6 @@ pub fn uncompress_dmg(
244242
compressed_file: &str,
245243
target: &Path,
246244
log: &Logger,
247-
os: &str,
248245
volume: &str,
249246
) -> Result<(), Error> {
250247
let dmg_file_name = Path::new(compressed_file)
@@ -255,24 +252,32 @@ pub fn uncompress_dmg(
255252
"Mounting {} and copying content to cache",
256253
dmg_file_name.to_str().unwrap_or_default()
257254
));
258-
let mut command = Command::new_single(format_one_arg(HDIUTIL_ATTACH_COMMAND, compressed_file));
255+
let mut command = Command::new(
256+
HDIUTIL_COMMAND,
257+
vec![String::from("attach"), compressed_file.to_string()],
258+
);
259259
log.trace(format!("Running command: {}", command.display()));
260-
run_shell_command_by_os(os, command)?;
260+
run_shell_command(command)?;
261261

262262
fs::create_dir_all(target)?;
263263
let target_folder = path_to_string(target);
264-
command = Command::new_single(format_three_args(
265-
CP_VOLUME_COMMAND,
266-
volume,
267-
volume,
268-
&target_folder,
269-
));
264+
command = Command::new(
265+
"cp",
266+
vec![
267+
String::from("-R"),
268+
format!("/Volumes/{}/{}.app", volume, volume),
269+
target_folder,
270+
],
271+
);
270272
log.trace(format!("Running command: {}", command.display()));
271-
run_shell_command_by_os(os, command)?;
273+
run_shell_command(command)?;
272274

273-
command = Command::new_single(format_one_arg(HDIUTIL_DETACH_COMMAND, volume));
275+
command = Command::new(
276+
HDIUTIL_COMMAND,
277+
vec![String::from("detach"), format!("/Volumes/{}", volume)],
278+
);
274279
log.trace(format!("Running command: {}", command.display()));
275-
run_shell_command_by_os(os, command)?;
280+
run_shell_command(command)?;
276281

277282
Ok(())
278283
}
@@ -309,7 +314,7 @@ pub fn uncompress_deb(
309314
Ok(())
310315
}
311316

312-
pub fn install_msi(msi_file: &str, log: &Logger, os: &str) -> Result<(), Error> {
317+
pub fn install_msi(msi_file: &str, log: &Logger, _os: &str) -> Result<(), Error> {
313318
let msi_file_name = Path::new(msi_file)
314319
.file_name()
315320
.unwrap_or_default()
@@ -319,9 +324,17 @@ pub fn install_msi(msi_file: &str, log: &Logger, os: &str) -> Result<(), Error>
319324
msi_file_name.to_str().unwrap_or_default()
320325
));
321326

322-
let command = Command::new_single(format_one_arg(MSIEXEC_INSTALL_COMMAND, msi_file));
327+
let command = Command::new(
328+
"msiexec",
329+
vec![
330+
String::from("/i"),
331+
msi_file.to_string(),
332+
String::from("/qn"),
333+
String::from("ALLOWDOWNGRADE=1"),
334+
],
335+
);
323336
log.trace(format!("Running command: {}", command.display()));
324-
run_shell_command_by_os(os, command)?;
337+
run_shell_command(command)?;
325338

326339
Ok(())
327340
}

rust/src/firefox.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@ use crate::metadata::{
2424
create_driver_metadata, get_driver_version_from_metadata, get_metadata, write_metadata,
2525
};
2626
use crate::{
27-
BETA, DASH_VERSION, DEV, ESR, LATEST_RELEASE, Logger, NIGHTLY, OFFLINE_REQUEST_ERR_MSG,
28-
REG_CURRENT_VERSION_ARG, STABLE, SeleniumManager, create_http_client, format_three_args,
29-
format_two_args,
27+
BETA, DASH_VERSION, DEV, ESR, LATEST_RELEASE, Logger, NIGHTLY, OFFLINE_REQUEST_ERR_MSG, STABLE,
28+
SeleniumManager, create_http_client, format_three_args, format_two_args,
3029
};
3130
use anyhow::Error;
3231
use anyhow::anyhow;
@@ -195,7 +194,7 @@ impl SeleniumManager for FirefoxManager {
195194
fn discover_browser_version(&mut self) -> Result<Option<String>, Error> {
196195
self.general_discover_browser_version(
197196
r"HKCU\Software\Mozilla\Mozilla Firefox",
198-
REG_CURRENT_VERSION_ARG,
197+
"CurrentVersion",
199198
DASH_VERSION,
200199
)
201200
}

rust/src/lib.rs

Lines changed: 49 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,7 @@ use crate::metadata::{
3939
};
4040
use crate::safari::{SAFARI_NAME, SAFARIDRIVER_NAME, SafariManager};
4141
use crate::safaritp::{SAFARITP_NAMES, SafariTPManager};
42-
use crate::shell::{
43-
Command, run_shell_command, run_shell_command_by_os, run_shell_command_with_log,
44-
};
42+
use crate::shell::{Command, run_shell_command, run_shell_command_with_log};
4543
use crate::stats::{Props, send_stats_to_plausible};
4644
use anyhow::Error;
4745
use anyhow::anyhow;
@@ -85,19 +83,9 @@ pub const CANARY: &str = "canary";
8583
pub const NIGHTLY: &str = "nightly";
8684
pub const ESR: &str = "esr";
8785
pub const REG_VERSION_ARG: &str = "version";
88-
pub const REG_CURRENT_VERSION_ARG: &str = "CurrentVersion";
8986
pub const REG_PV_ARG: &str = "pv";
90-
pub const PLIST_COMMAND: &str =
91-
r#"/usr/libexec/PlistBuddy -c "print :CFBundleShortVersionString" {}/Contents/Info.plist"#;
92-
pub const HDIUTIL_ATTACH_COMMAND: &str = "hdiutil attach {}";
93-
pub const HDIUTIL_DETACH_COMMAND: &str = "hdiutil detach /Volumes/{}";
94-
pub const CP_VOLUME_COMMAND: &str = "cp -R /Volumes/{}/{}.app {}";
95-
pub const MSIEXEC_INSTALL_COMMAND: &str = "start /wait msiexec /i {} /qn ALLOWDOWNGRADE=1";
96-
pub const WINDOWS_CHECK_ADMIN_COMMAND: &str = "net session";
97-
pub const DASH_VERSION: &str = "{}{}{} -v";
98-
pub const DASH_DASH_VERSION: &str = "{}{}{} --version";
99-
pub const DOUBLE_QUOTE: &str = r#"""#;
100-
pub const SINGLE_QUOTE: &str = "'";
87+
pub const DASH_VERSION: &str = "-v";
88+
pub const DASH_DASH_VERSION: &str = "--version";
10189
pub const ENV_PROGRAM_FILES: &str = "PROGRAMFILES";
10290
pub const ENV_PROGRAM_FILES_X86: &str = "PROGRAMFILES(X86)";
10391
pub const ENV_LOCALAPPDATA: &str = "LOCALAPPDATA";
@@ -109,8 +97,6 @@ pub const ARCH_ARM64: &str = "arm64";
10997
pub const ARCH_ARM7L: &str = "arm7l";
11098
pub const ARCH_OTHER: &str = "other";
11199
pub const TTL_SEC: u64 = 3600;
112-
pub const UNAME_COMMAND: &str = "uname -{}";
113-
pub const ESCAPE_COMMAND: &str = r#"printf %q "{}""#;
114100
pub const SNAPSHOT: &str = "SNAPSHOT";
115101
pub const OFFLINE_REQUEST_ERR_MSG: &str = "Unable to discover proper {} version in offline mode";
116102
pub const OFFLINE_DOWNLOAD_ERR_MSG: &str = "Unable to download {} in offline mode";
@@ -478,11 +464,8 @@ pub trait SeleniumManager {
478464
));
479465
let mut browser_version: Option<String> = None;
480466
for driver_version_command in commands.into_iter() {
481-
let output = match run_shell_command_with_log(
482-
self.get_logger(),
483-
self.get_os(),
484-
driver_version_command,
485-
) {
467+
let output = match run_shell_command_with_log(self.get_logger(), driver_version_command)
468+
{
486469
Ok(out) => out,
487470
Err(_) => continue,
488471
};
@@ -676,13 +659,9 @@ pub trait SeleniumManager {
676659
}
677660

678661
fn find_driver_in_path(&self) -> (Option<String>, Option<String>) {
679-
let driver_version_command = Command::new_single(format_three_args(
680-
DASH_DASH_VERSION,
681-
self.get_driver_name(),
682-
"",
683-
"",
684-
));
685-
match run_shell_command_by_os(self.get_os(), driver_version_command) {
662+
let driver_version_command =
663+
Command::new(self.get_driver_name(), vec![String::from("--version")]);
664+
match run_shell_command(driver_version_command) {
686665
Ok(output) => {
687666
let parsed_version = parse_version(output, self.get_logger()).unwrap_or_default();
688667
if !parsed_version.is_empty() {
@@ -713,8 +692,8 @@ pub trait SeleniumManager {
713692
fn is_windows_admin(&self) -> bool {
714693
let os = self.get_os();
715694
if WINDOWS.is(os) {
716-
let command = Command::new_single(WINDOWS_CHECK_ADMIN_COMMAND.to_string());
717-
let output = run_shell_command_by_os(os, command).unwrap_or_default();
695+
let command = Command::new("net", vec![String::from("session")]);
696+
let output = run_shell_command(command).unwrap_or_default();
718697
!output.is_empty() && !output.contains("error") && !output.contains("not recognized")
719698
} else {
720699
false
@@ -973,7 +952,7 @@ pub trait SeleniumManager {
973952
is_driver_in_path: &bool,
974953
err: Error,
975954
) -> Result<(), Error> {
976-
if *is_driver_in_path {
955+
if *is_driver_in_path && self.is_fallback_driver_from_cache() {
977956
self.get_logger().debug_or_warn(
978957
format!("Exception managing {}: {}", self.get_browser_name(), err),
979958
self.is_offline(),
@@ -1213,35 +1192,22 @@ pub trait SeleniumManager {
12131192
return Ok(get_win_file_version(&escaped_browser_path));
12141193
}
12151194
if !self.is_browser_version_unstable() {
1216-
let reg_command =
1217-
Command::new_multiple(vec!["REG", "QUERY", reg_key, "/v", reg_version_arg]);
1195+
let reg_command = Command::new(
1196+
"REG",
1197+
vec![
1198+
String::from("QUERY"),
1199+
reg_key.to_string(),
1200+
String::from("/v"),
1201+
reg_version_arg.to_string(),
1202+
],
1203+
);
12181204
commands.push(reg_command);
12191205
}
12201206
} else if !escaped_browser_path.is_empty() {
1221-
commands.push(Command::new_single(format_three_args(
1222-
cmd_version_arg,
1223-
"",
1224-
&escaped_browser_path,
1225-
"",
1226-
)));
1227-
commands.push(Command::new_single(format_three_args(
1228-
cmd_version_arg,
1229-
DOUBLE_QUOTE,
1230-
&browser_path,
1231-
DOUBLE_QUOTE,
1232-
)));
1233-
commands.push(Command::new_single(format_three_args(
1234-
cmd_version_arg,
1235-
SINGLE_QUOTE,
1236-
&browser_path,
1237-
SINGLE_QUOTE,
1238-
)));
1239-
commands.push(Command::new_single(format_three_args(
1240-
cmd_version_arg,
1241-
"",
1242-
&browser_path,
1243-
"",
1244-
)));
1207+
commands.push(Command::new(
1208+
escaped_browser_path,
1209+
vec![cmd_version_arg.to_string()],
1210+
));
12451211
}
12461212

12471213
Ok(self.detect_browser_version(commands))
@@ -1259,7 +1225,14 @@ pub trait SeleniumManager {
12591225
}
12601226
}
12611227
if MACOS.is(self.get_os()) {
1262-
let plist_command = Command::new_single(format_one_arg(PLIST_COMMAND, &browser_path));
1228+
let plist_command = Command::new(
1229+
"/usr/libexec/PlistBuddy",
1230+
vec![
1231+
String::from("-c"),
1232+
String::from("print :CFBundleShortVersionString"),
1233+
format!("{}/Contents/Info.plist", browser_path),
1234+
],
1235+
);
12631236
commands.push(plist_command);
12641237
} else {
12651238
return Ok(None);
@@ -1492,16 +1465,6 @@ pub trait SeleniumManager {
14921465

14931466
if path.exists() {
14941467
escaped_path = self.canonicalize_path(path.to_path_buf());
1495-
if WINDOWS.is(self.get_os()) {
1496-
escaped_path = escaped_path.replace('\\', "\\\\");
1497-
} else {
1498-
let escape_command =
1499-
Command::new_single(format_one_arg(ESCAPE_COMMAND, escaped_path.as_str()));
1500-
escaped_path = run_shell_command("bash", "-c", escape_command).unwrap_or_default();
1501-
if escaped_path.is_empty() {
1502-
escaped_path = string_path.clone();
1503-
}
1504-
}
15051468
}
15061469
if !string_path.eq(&escaped_path) {
15071470
self.get_logger().trace(format!(
@@ -1735,6 +1698,23 @@ pub fn create_http_client(timeout: u64, proxy: &str) -> Result<Client, Error> {
17351698
Ok(client_builder.build().unwrap_or_default())
17361699
}
17371700

1701+
#[cfg(test)]
1702+
mod tests {
1703+
use super::*;
1704+
1705+
#[test]
1706+
fn get_escaped_path_returns_canonical_path_without_shell_escaping() {
1707+
let tmp = tempfile::tempdir().unwrap();
1708+
let folder = tmp.path().join("space dir");
1709+
std::fs::create_dir(&folder).unwrap();
1710+
1711+
let manager = crate::chrome::ChromeManager::new().unwrap();
1712+
let escaped = manager.get_escaped_path(folder.to_string_lossy().to_string());
1713+
1714+
assert_eq!(escaped, manager.canonicalize_path(folder));
1715+
}
1716+
}
1717+
17381718
pub fn format_one_arg(string: &str, arg1: &str) -> String {
17391719
string.replacen("{}", arg1, 1)
17401720
}

0 commit comments

Comments
 (0)