Skip to content

ls panics (unwrap None) on --time-style=posix- (empty after prefix strip) #12629

@leeewee

Description

@leeewee

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions