Skip to content

numfmt: report oversized --padding instead of aborting#12561

Open
leeewee wants to merge 1 commit into
uutils:mainfrom
leeewee:fix-numfmt-padding-capacity-overflow
Open

numfmt: report oversized --padding instead of aborting#12561
leeewee wants to merge 1 commit into
uutils:mainfrom
leeewee:fix-numfmt-padding-capacity-overflow

Conversation

@leeewee

@leeewee leeewee commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Fixes #12560.

Problem

A large --padding makes pad_string (added to handle widths beyond
format!'s u16 cap) call String::with_capacity(width) with an unbounded,
user-controlled width, crashing the process:

$ numfmt --padding=9000000000000000000 1
memory allocation of 9000000000000000000 bytes failed
Aborted (core dumped)            # exit 134

$ numfmt --padding=-9223372036854775808 1
thread 'main' panicked at .../alloc/src/string.rs: capacity overflow
Aborted (core dumped)            # exit 134

(-9223372036854775808 is isize::MIN; its magnitude is isize::MAX + 1,
which overflows with_capacity's capacity check deterministically.)

GNU reports this cleanly and exits 1:

$ numfmt --padding=9000000000000000000 1
numfmt: memory exhausted         # exit 1

Fix

Validate the padding up front in uumain — before reading any input — with a
fallible try_reserve_exact, and fail with memory exhausted (exit 1) on
overflow/allocation failure.

Doing the check up front (rather than lazily inside pad_string) also matches
GNU's observable behavior:

  • it fails immediately and does not block on stdin
    (numfmt --padding=-9223372036854775808 no longer waits for input);
  • it does not silently exit 0 when there is no input.

memory exhausted is surfaced as NumfmtError::IoError, which exits 1 —
consistent with how uutils numfmt already matches GNU's other exit codes
(option errors → 1, input-conversion errors → 2).

Tests

Added test_padding_too_large_fails_cleanly. Full numfmt suite passes
(152 integration + unit tests); cargo fmt/clippy clean.

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

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/tail-n0f (passes in this run but fails in the 'main' branch)
Note: The gnu test tests/seq/seq-epipe is now being skipped but was previously passing.

@leeewee leeewee force-pushed the fix-numfmt-padding-capacity-overflow branch from 70a8b32 to e1f7963 Compare June 2, 2026 06:09
Comment thread tests/by-util/test_numfmt.rs Outdated
Comment thread tests/by-util/test_numfmt.rs Outdated
Comment thread src/uu/numfmt/src/numfmt.rs Outdated
A large `--padding` made `pad_string` call `String::with_capacity(width)`
with an unbounded, user-controlled width, aborting the process (allocation
failure, or a `capacity overflow` panic for `--padding=-9223372036854775808`,
whose magnitude exceeds `isize::MAX`).

Validate the padding up front, before reading any input, and fail with a
clean `memory exhausted` error (exit 1) — matching GNU. Doing it up front
also matches GNU's behavior of not blocking on stdin and not silently
succeeding on empty input.

Fixes uutils#12560.
@leeewee leeewee force-pushed the fix-numfmt-padding-capacity-overflow branch from e1f7963 to ae33b10 Compare June 2, 2026 06:35
@leeewee

leeewee commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

All done — addressed all three comments.

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.

numfmt aborts/panics on a large --padding (unbounded allocation)

2 participants