diff --git a/src/uu/du/src/du.rs b/src/uu/du/src/du.rs index fa91da7ac24..e748d4d7fc6 100644 --- a/src/uu/du/src/du.rs +++ b/src/uu/du/src/du.rs @@ -1233,9 +1233,12 @@ fn parse_time_style(s: Option<&String>) -> UResult { // the string starts with +, and ignore "locale". Ok(s) => { let s = s.strip_prefix("posix-").unwrap_or(s.as_str()); - let s = match s.chars().next().unwrap() { - '+' => s.split('\n').next().unwrap(), - _ => s, + // `s` can be empty here (e.g. TIME_STYLE=posix-), so test the + // prefix instead of unwrapping the first char. + let s = if s.starts_with('+') { + s.split('\n').next().unwrap() + } else { + s }; match s { "locale" => None, @@ -1251,9 +1254,9 @@ fn parse_time_style(s: Option<&String>) -> UResult { "full-iso" => Ok(format::FULL_ISO.to_string()), "long-iso" => Ok(format::LONG_ISO.to_string()), "iso" => Ok(format::ISO.to_string()), - _ => match s.chars().next().unwrap() { - '+' => Ok(s[1..].to_string()), - _ => Err(DuError::InvalidTimeStyleArg(s).into()), + _ => match s.strip_prefix('+') { + Some(rest) => Ok(rest.to_string()), + None => Err(DuError::InvalidTimeStyleArg(s).into()), }, }, None => Ok(format::LONG_ISO.to_string()), diff --git a/src/uu/ls/src/config.rs b/src/uu/ls/src/config.rs index 3a879b83735..fc788e85425 100644 --- a/src/uu/ls/src/config.rs +++ b/src/uu/ls/src/config.rs @@ -1054,19 +1054,19 @@ fn parse_time_style(options: &clap::ArgMatches) -> Result<(String, Option ok(LOCALE_FORMAT), - _ => match field.chars().next().unwrap() { - '+' => { - // recent/older formats are (optionally) separated by a newline - let mut it = field[1..].split('\n'); - let recent = it.next().unwrap_or_default(); - let older = it.next(); - match it.next() { - None => ok((recent, older)), - Some(_) => Err(LsError::TimeStyleParseError(String::from(field))), - } + // `field` can be empty here (e.g. --time-style=posix-), so test + // the prefix instead of unwrapping the first char. + _ if field.starts_with('+') => { + // recent/older formats are (optionally) separated by a newline + let mut it = field[1..].split('\n'); + let recent = it.next().unwrap_or_default(); + let older = it.next(); + match it.next() { + None => ok((recent, older)), + Some(_) => Err(LsError::TimeStyleParseError(String::from(field))), } - _ => Err(LsError::TimeStyleParseError(String::from(field))), - }, + } + _ => Err(LsError::TimeStyleParseError(String::from(field))), } } } else if options.get_flag(options::FULL_TIME) { diff --git a/tests/by-util/test_du.rs b/tests/by-util/test_du.rs index 7dfda01fd4a..30e8ab111e7 100644 --- a/tests/by-util/test_du.rs +++ b/tests/by-util/test_du.rs @@ -188,6 +188,21 @@ fn test_du_with_posixly_correct() { assert_eq!(expected, result); } +#[test] +fn test_du_time_style_empty() { + let ts = TestScenario::new(util_name!()); + ts.fixtures.mkdir("a"); + ts.ucmd() + .args(&["--time", "--time-style=", "a"]) + .fails_with_code(1) + .stderr_contains("du: invalid argument '' for 'time style'"); + ts.ucmd() + .args(&["--time", "a"]) + .env("TIME_STYLE", "posix-") + .fails_with_code(1) + .stderr_contains("du: invalid argument '' for 'time style'"); +} + #[test] fn test_du_zero_env_block_size() { let ts = TestScenario::new(util_name!()); diff --git a/tests/by-util/test_ls.rs b/tests/by-util/test_ls.rs index 55e9b22e112..8965aaadc7c 100644 --- a/tests/by-util/test_ls.rs +++ b/tests/by-util/test_ls.rs @@ -167,6 +167,15 @@ fn test_invalid_value_time_style() { .no_stderr(); } +#[test] +fn test_time_style_empty_after_posix_prefix() { + new_ucmd!() + .arg("-l") + .arg("--time-style=posix-") + .fails_with_code(2) + .stderr_contains("ls: invalid --time-style argument ''"); +} + #[test] fn test_ls_ls() { new_ucmd!().succeeds();