Summary
A stat -c format string that contains a multibyte (non-ASCII) character immediately before an invalid % directive panics with "byte index N is not a char boundary" and aborts (exit 134). The format parser tracks positions as character indices, but the error-reporting helper check_bound builds its "invalid directive" message by byte-indexing the format string, so a preceding multibyte char makes the byte index land mid-UTF-8-character and the slice panics.
Steps to reproduce
$ stat -c '€%-' /etc/hostname
thread 'main' panicked at src/uu/stat/src/stat.rs:88:33:
byte index 1 is not a char boundary; it is inside '€' (bytes 0..3) of `€%-`
$ echo $?
134
(Other triggers: 'ä%0', '€%.'.)
Expected behavior
Match GNU: emit the leading field, report the invalid directive, and exit 1
without crashing.
$ /usr/bin/stat -c '€%-' /etc/hostname
€/usr/bin/stat: '%-': invalid directive
$ echo $?
1
Actual behavior
uutils panics on the str slice and aborts with exit code 134. Only the invalid-directive error path is affected; a purely-ASCII format string hits the same check_bound path cleanly because char indices and byte indices coincide.
Found by our static analysis tooling.
Summary
A
stat -cformat string that contains a multibyte (non-ASCII) character immediately before an invalid%directive panics with "byte index N is not a char boundary" and aborts (exit 134). The format parser tracks positions as character indices, but the error-reporting helpercheck_boundbuilds its "invalid directive" message by byte-indexing the format string, so a preceding multibyte char makes the byte index land mid-UTF-8-character and the slice panics.Steps to reproduce
(Other triggers:
'ä%0','€%.'.)Expected behavior
Match GNU: emit the leading field, report the invalid directive, and exit 1
without crashing.
Actual behavior
uutils panics on the str slice and aborts with exit code 134. Only the invalid-directive error path is affected; a purely-ASCII format string hits the same
check_boundpath cleanly because char indices and byte indices coincide.Found by our static analysis tooling.