Skip to content

stat: fix overflow on out-of-range octal escape - #14371

Merged
cakebaker merged 1 commit into
uutils:mainfrom
harshasiddartha:stat-octal-escape-overflow
Sep 4, 2026
Merged

stat: fix overflow on out-of-range octal escape#14371
cakebaker merged 1 commit into
uutils:mainfrom
harshasiddartha:stat-octal-escape-overflow

Conversation

@harshasiddartha

@harshasiddartha harshasiddartha commented Sep 3, 2026

Copy link
Copy Markdown
Contributor

What was wrong

stat --printf '\400' (and any \NNN escape from \400 through \777) aborted instead of printing a byte:

$ ./target/debug/coreutils stat --printf '\400' . >/dev/null
thread 'main' panicked at src/uu/stat/src/stat.rs:950:33:
attempt to multiply with overflow
$ echo $?
101

Any build with overflow-checks enabled (debug builds by default, or release with -C overflow-checks) hits this.

Root cause

handle_escape_sequences accumulated the octal escape in a u8:

let mut value = 0u8;
…
value = value * 8 + digit as u8;

Three octal digits can encode values up to 511, so as soon as the accumulated value passes u8::MAX the multiply overflows.

The fix

Accumulate in a u32 — three octal digits reach at most 511, so the arithmetic can no longer overflow — and keep the low byte when building the Token::Byte. That makes \400 print 0x00 and \777 print 0xFF, matching what GNU stat outputs for an out-of-range octal escape. In-range escapes are unaffected. Only --printf is affected: generate_tokens interprets backslash escapes for --printf and treats them literally for -c/--format, matching GNU.

The fix was written from scratch; no GNU source was consulted or copied, only GNU's observable output for these escapes.

How it was tested

  • New regression test test_printf_octal_out_of_range in tests/by-util/test_stat.rs asserts that --printf=\400\777 succeeds and emits the bytes 00 ff. It fails on main (the command exits 101) and passes with this change.
  • The full stat test suite passes: cargo test --no-default-features --features stat --test tests test_stat → 34 passed, 0 failed.
  • cargo clippy -p uu_stat --no-default-features --all-targets is clean, and cargo fmt reports no changes.

Fixes #14346

A \NNN escape whose value exceeds 255 (\400 through \777) was
accumulated in a u8, so the multiply overflowed and a build with
overflow-checks panicked with exit code 101.

Accumulate the escape in a u32 and keep the low byte, so \400 prints
0x00 and \777 prints 0xFF, matching GNU.
@github-actions

github-actions Bot commented Sep 4, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

GNU test failed: tests/dd/misc. tests/dd/misc is passing on 'main'. Maybe you have to rebase?
GNU test failed: tests/df/over-mount-device. tests/df/over-mount-device is passing on 'main'. Maybe you have to rebase?
Skipping an intermittent issue tests/date/date-locale-hour (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/inotify-dir-recreate (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/cat/splice is no longer failing!
Congrats! The gnu test tests/cp/cp-a-selinux is no longer failing!
Congrats! The gnu test tests/cut/cut is no longer failing!
Congrats! The gnu test tests/cut/mb-non-utf8 is no longer failing!
Congrats! The gnu test tests/dd/partial-write is no longer failing!
Congrats! The gnu test tests/expand/mb is no longer failing!
Congrats! The gnu test tests/ls/stat-free-symlinks is no longer failing!
Congrats! The gnu test tests/misc/close-stdout is no longer failing!
Congrats! The gnu test tests/mktemp/write-error is no longer failing!
Congrats! The gnu test tests/mv/dir2dir is no longer failing!
Congrats! The gnu test tests/mv/mv-exchange is no longer failing!
Congrats! The gnu test tests/nl/multibyte is no longer failing!
Congrats! The gnu test tests/od/od-float is no longer failing!
Congrats! The gnu test tests/od/od-j is no longer failing!
Congrats! The gnu test tests/ptx/ptx-overrun is no longer failing!
Congrats! The gnu test tests/sort/sort-merge-fdlimit is no longer failing!
Congrats! The gnu test tests/unexpand/mb is no longer failing!
Note: The gnu test tests/dd/fail-ftruncate-fstat was skipped on 'main' but is now failing.

@cakebaker
cakebaker merged commit 975bf52 into uutils:main Sep 4, 2026
97 of 101 checks passed
@cakebaker

Copy link
Copy Markdown
Contributor

Thanks for your PR!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

stat: arithmetic overflow (overflow-checks) on a \NNN octal escape ≥ \400

2 participants