Summary
Running ls -l --time-style=posix- makes ls panic with called 'Option::unwrap()' on a 'None' value and abort (exit 134). The value posix- passes clap's non-empty check, but parse_time_style strips the posix- prefix, leaving an empty field; that field matches no named style and falls to the _ arm, where field.chars().next().unwrap() unwraps None. GNU rejects the empty value with an "ambiguous argument" diagnostic and exits 2 without crashing.
Steps to reproduce
$ ls -l --time-style=posix- .
thread 'main' panicked at src/uu/ls/src/config.rs:1057:49:
called `Option::unwrap()` on a `None` value
$ echo $?
134
Expected behavior
Match GNU: report the error and exit non-zero without crashing.
$ /usr/bin/ls -l --time-style=posix- .
/usr/bin/ls: ambiguous argument '' for 'time style'
Valid arguments are:
- 'full-iso'
- 'long-iso'
- 'iso'
- 'locale'
- '+FORMAT' (e.g., +%H:%M) for a 'date'-style format
$ echo $?
2
Actual behavior
ls panics and aborts with exit code 134. The empty field reaches the _ arm of the match field and field.chars().next() returns None, which is then unwrapped. The long format (-l) is required to reach the time-style path. Because dir and vdir share uu_ls, dir -l --time-style=posix- and vdir -l --time-style=posix- panic identically.
Root cause
The posix- prefix is stripped around config.rs:1033:
// src/uu/ls/src/config.rs:1033
let field = if let Some(field) = field.strip_prefix("posix-") {
leaving an empty field, which then hits the unconditional unwrap:
// src/uu/ls/src/config.rs:1057
_ => match field.chars().next().unwrap() {
clap requires a non-empty --time-style value, but posix- satisfies that and only becomes empty after the prefix strip, so validation does not catch it. The fix is to treat an empty field as the ambiguous-argument error GNU emits (the LsError::TimeStyleParseError path) rather than calling .chars().next().unwrap().
Found by our static analysis tooling.
Summary
Running
ls -l --time-style=posix-makeslspanic withcalled 'Option::unwrap()' on a 'None' valueand abort (exit 134). The valueposix-passes clap's non-empty check, butparse_time_stylestrips theposix-prefix, leaving an emptyfield; that field matches no named style and falls to the_arm, wherefield.chars().next().unwrap()unwrapsNone. GNU rejects the empty value with an "ambiguous argument" diagnostic and exits 2 without crashing.Steps to reproduce
Expected behavior
Match GNU: report the error and exit non-zero without crashing.
Actual behavior
lspanics and aborts with exit code 134. The emptyfieldreaches the_arm of thematch fieldandfield.chars().next()returnsNone, which is then unwrapped. The long format (-l) is required to reach the time-style path. Becausedirandvdirshareuu_ls,dir -l --time-style=posix-andvdir -l --time-style=posix-panic identically.Root cause
The
posix-prefix is stripped aroundconfig.rs:1033:leaving an empty
field, which then hits the unconditional unwrap:claprequires a non-empty--time-stylevalue, butposix-satisfies that and only becomes empty after the prefix strip, so validation does not catch it. The fix is to treat an emptyfieldas the ambiguous-argument error GNU emits (theLsError::TimeStyleParseErrorpath) rather than calling.chars().next().unwrap().Found by our static analysis tooling.