From 4198dfbb8c37cad6f7a7b1ae21fc5791372db7ea Mon Sep 17 00:00:00 2001 From: Alex Zenla Date: Sun, 4 Oct 2026 14:45:50 -0700 Subject: [PATCH] fix(eficore): keep backslashes in command-line arguments --- Cargo.lock | 7 ------ Cargo.toml | 4 ---- crates/eficore/Cargo.toml | 1 - crates/eficore/src/env.rs | 48 +++++++++++++++++++++++++++++++-------- 4 files changed, 39 insertions(+), 21 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e847e33..f9c5f84 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -126,7 +126,6 @@ dependencies = [ "anyhow", "bitflags", "log", - "shlex", "spin", "uefi", "uefi-raw", @@ -339,12 +338,6 @@ dependencies = [ "digest", ] -[[package]] -name = "shlex" -version = "2.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8fadd59c855ef2080decdef8ff161eb6661b86933c9d82e5ba29dc602a55aba" - [[package]] name = "simd-adler32" version = "0.3.10" diff --git a/Cargo.toml b/Cargo.toml index 5fc915b..338997a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,10 +50,6 @@ default-features = false version = "0.11.0" default-features = false -[workspace.dependencies.shlex] -version = "2.0.1" -default-features = false - [workspace.dependencies.toml] version = "1.1.6" default-features = false diff --git a/crates/eficore/Cargo.toml b/crates/eficore/Cargo.toml index 45f7e4a..31b68bb 100644 --- a/crates/eficore/Cargo.toml +++ b/crates/eficore/Cargo.toml @@ -11,7 +11,6 @@ edition.workspace = true anyhow.workspace = true bitflags.workspace = true log.workspace = true -shlex.workspace = true spin.workspace = true uefi.workspace = true uefi-raw.workspace = true diff --git a/crates/eficore/src/env.rs b/crates/eficore/src/env.rs index 48c26d1..b58c4e7 100644 --- a/crates/eficore/src/env.rs +++ b/crates/eficore/src/env.rs @@ -1,4 +1,4 @@ -use alloc::string::{String, ToString}; +use alloc::string::String; use alloc::vec::Vec; use anyhow::{Context, Result}; use uefi::proto::loaded_image::LoadedImage; @@ -33,14 +33,9 @@ pub fn args() -> Result> { .collect::>(); let options = String::from_utf16_lossy(&options); - // Use shlex to parse the options. - // If shlex fails, we will perform a simple whitespace split. - let mut args = shlex::split(&options).unwrap_or_else(|| { - options - .split_ascii_whitespace() - .map(|string| string.to_string()) - .collect::>() - }); + // Split the options on whitespace, keeping quoted text together. + // Backslashes are kept as they are, since UEFI paths use them as separators. + let mut args = split_options(&options); // Correct firmware that may add invalid arguments at the start. // Witnessed this on a Dell Precision 5690 when direct booting. @@ -66,3 +61,38 @@ pub fn args() -> Result> { Ok(args) } + +/// Splits `options` into arguments on whitespace. Text in single or double quotes is kept together. +fn split_options(options: &str) -> Vec { + let mut args = Vec::new(); + let mut current = String::new(); + let mut in_arg = false; + let mut quote = None; + + for c in options.chars() { + match quote { + Some(q) if c == q => quote = None, + Some(_) => current.push(c), + None if c == '"' || c == '\'' => { + quote = Some(c); + in_arg = true; + } + None if c.is_whitespace() => { + if in_arg { + args.push(core::mem::take(&mut current)); + in_arg = false; + } + } + None => { + current.push(c); + in_arg = true; + } + } + } + + if in_arg { + args.push(current); + } + + args +}