Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ensure systemRoot() always has trailing separator character #616

Merged
merged 9 commits into from
Dec 18, 2024
36 changes: 36 additions & 0 deletions dsc_lib/src/functions/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,15 @@ impl Function for Path {
debug!("Executing path function with args: {:?}", args);

let mut path = PathBuf::new();
let mut first = true;
for arg in args {
if let Value::String(s) = arg {
// if first argument is a drive letter, add it with a separator suffix as PathBuf.push() doesn't add it
tgauth marked this conversation as resolved.
Show resolved Hide resolved
if first && s.len() == 2 && s.chars().nth(1).unwrap() == ':' {
SteveL-MSFT marked this conversation as resolved.
Show resolved Hide resolved
path.push(s.to_owned() + std::path::MAIN_SEPARATOR.to_string().as_str());
first = false;
continue;
}
path.push(s);
} else {
return Err(DscError::Parser("Arguments must all be strings".to_string()));
Expand All @@ -48,6 +55,35 @@ mod tests {
use crate::configure::context::Context;
use crate::parser::Statement;

#[test]
fn start_with_drive_letter() {
let mut parser = Statement::new().unwrap();
let separator = std::path::MAIN_SEPARATOR;
let result = parser.parse_and_execute("[path('C:','test')]", &Context::new()).unwrap();
assert_eq!(result, format!("C:{separator}test"));
}

#[test]
fn drive_letter_in_middle() {
let mut parser = Statement::new().unwrap();
let separator = std::path::MAIN_SEPARATOR;
let result = parser.parse_and_execute("[path('a','C:','test')]", &Context::new()).unwrap();

// if any part of the path is absolute, it replaces it instead of appending
#[cfg(target_os = "windows")]
assert_eq!(result, format!("C:{separator}test"));
#[cfg(not(target_os = "windows"))]
assert_eq!(result, format!("a{separator}C:{separator}test"));
}

#[test]
fn unix_absolute_path() {
let mut parser = Statement::new().unwrap();
let separator = std::path::MAIN_SEPARATOR;
let result = parser.parse_and_execute("[path('/','a','b')]", &Context::new()).unwrap();
assert_eq!(result, format!("/a{separator}b"));
}

#[test]
fn two_args() {
let mut parser = Statement::new().unwrap();
Expand Down
Loading