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

env: only long options are allowed to contain '=' #6711

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 83 additions & 0 deletions src/uu/env/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,7 @@ impl EnvAppData {
original_args: &Vec<OsString>,
) -> UResult<Vec<std::ffi::OsString>> {
let mut all_args: Vec<std::ffi::OsString> = Vec::new();

for arg in original_args {
match arg {
b if check_and_handle_string_args(b, "--split-string", &mut all_args, None)? => {
Expand All @@ -370,6 +371,19 @@ impl EnvAppData {
self.had_string_argument = true;
}
_ => {
let arg_str = arg.to_string_lossy();

// Only long option is allowed to contain '='
if arg_str.contains('=')
&& arg_str.starts_with('-')
&& !arg_str.starts_with("--")
{
return Err(USimpleError::new(
1,
format!("cannot unset '{}': Invalid argument", &arg_str[2..]),
));
}

all_args.push(arg.clone());
}
}
Expand Down Expand Up @@ -751,4 +765,73 @@ mod tests {
parse_args_from_str(&NCvt::convert(r#"-i A='B \' C'"#)).unwrap()
);
}

#[test]
fn test_apply_unset_env_vars_invalid_equal_sign() {
let opts = Options {
ignore_env: false,
line_ending: uucore::line_ending::LineEnding::Newline,
running_directory: None,
files: vec![],
unsets: vec![OsStr::new("INVALID=VAR")],
sets: vec![],
program: vec![],
argv0: None,
#[cfg(unix)]
ignore_signal: vec![],
};

let result = apply_unset_env_vars(&opts);
assert!(result.is_err());

let err = result.unwrap_err();
assert_eq!(err.code(), 125);
assert_eq!(
err.to_string(),
"cannot unset 'INVALID=VAR': Invalid argument"
);
}

#[test]
fn test_process_all_string_arguments() {
// Define test cases with expected outcomes
let test_cases = vec![
// Argument with short option and '=' (should fail)
(
vec![OsString::from("-u=o")],
Err("cannot unset '=o': Invalid argument".to_string()),
),
// Argument with long option and '=' (should succeed)
(vec![OsString::from("--unset=o")], Ok(())),
// Argument with short option and no '=' (should succeed)
(vec![OsString::from("-u o")], Ok(())),
// Set env variable (should succeed)
(vec![OsString::from("u=o")], Ok(())),
// Empty assignment (should succeed)
(vec![OsString::from("=")], Ok(())),
// Argument ends with '='
(vec![OsString::from("--split-string=X=Y=")], Ok(())),
// No argument (should succeed)
(vec![OsString::from("")], Ok(())),
// TODO: implement handling of empty parameter value
// (vec![OsString::from("--unset=")], Err("env: cannot unset ‘’: Invalid argument".to_string())),
];

for (input_args, expected) in test_cases {
let mut env_app_data = EnvAppData::default();

let result = env_app_data.process_all_string_arguments(&input_args);

match expected {
Ok(()) => {
assert!(result.is_ok());
}
Err(expected_err) => {
assert!(result.is_err());
let err = result.unwrap_err();
assert_eq!(err.to_string(), expected_err);
}
}
}
}
}
Loading