Skip to content

unexpand: reject too-large --tabs increment instead of overflowing#13383

Merged
sylvestre merged 3 commits into
uutils:mainfrom
santhreal:fix/unexpand-tabstop-overflow
Jul 15, 2026
Merged

unexpand: reject too-large --tabs increment instead of overflowing#13383
sylvestre merged 3 commits into
uutils:mainfrom
santhreal:fix/unexpand-tabstop-overflow

Conversation

@santhreal

Copy link
Copy Markdown
Contributor

Summary

unexpand --tabs=N,+M adds one tab stop at N + M. When N is near usize::MAX, that addition overflowed:

  • under overflow checks (debug builds) it aborts:

    $ printf '\t\n' | unexpand --tabs=18446744073709551615,+1
    thread 'main' panicked at src/uu/unexpand/src/unexpand.rs:120: attempt to add with overflow
  • in release builds it wraps to 0, which then fails the "tab sizes must be ascending" check for the wrong reason.

Use checked_add and reject the value as TabSizeTooLarge ("tab stop value is too large"), matching GNU and the existing handling of a single over-large tab number in parse_tab_num.

Fixes #13378.

Test

Added test_extended_tabstop_increment_overflow asserting --tabs=<usize::MAX>,+1 fails with "tab stop value is too large". All 37 unexpand tests pass; cargo clippy --features unexpand --all-targets -- -D warnings and cargo fmt are clean.

…wing

`--tabs=N,+M` adds an extra tab stop at `N + M`. When `N` is near
`usize::MAX` the sum overflowed: it aborts under overflow checks and, in
release builds, wraps to a bogus stop that then fails the ascending check
for the wrong reason. Use `checked_add` and reject the value as
`TabSizeTooLarge` ("tab stop value is too large"), matching GNU and the
existing handling of a single over-large tab number in `parse_tab_num`.

Fixes uutils#13378
@github-actions

github-actions Bot commented Jul 13, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/cut/bounded-memory (passes in this run but fails in the 'main' branch)

Comment thread src/uu/unexpand/src/unexpand.rs Outdated
Comment on lines +120 to +122
// A near-maximal last stop plus the increment can exceed `usize::MAX`.
// Reject it as too large (matching GNU) instead of overflowing, which
// aborts under overflow checks and wraps to a bogus stop otherwise.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

a one line comment is probably enough

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Address review feedback: a one-line comment is enough.
Comment thread tests/by-util/test_unexpand.rs Outdated
Comment on lines +257 to +259
// `--tabs=N,+M` adds one stop at `N + M`. When `N` is near `usize::MAX`,
// that sum must be rejected as too large rather than overflowing (which
// aborts under overflow checks and wraps to a bogus stop otherwise).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sorry but same here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed

Address review feedback: a one-line comment is enough.
@sylvestre sylvestre merged commit 4449de7 into uutils:main Jul 15, 2026
176 of 246 checks passed
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.

unexpand: tab-stop increment overflows on a near-maximal ​--tabs=N,+M

2 participants