Skip to content

fmt: reject --tab-width values above MAX_TAB_WIDTH (2500) - #14666

Open
koopatroopa787 wants to merge 2 commits into
uutils:mainfrom
koopatroopa787:fix-fmt-tab-width-overflow
Open

koopatroopa787 wants to merge 2 commits into
uutils:mainfrom
koopatroopa787:fix-fmt-tab-width-overflow

Conversation

@koopatroopa787

Copy link
Copy Markdown
Contributor

Problem

fmt --tab-width/-T accepted any usize value with no upper bound. Large values flowed directly into arithmetic in linebreak.rs and parasplit.rs, causing panics at 11 distinct sites under overflow-checks builds and undefined behaviour (wrapping arithmetic) in release builds.

Examples from #14460:

$ printf '\thello world' | fmt -T 18446744073709551615
thread 'main' panicked at src/uu/fmt/src/linebreak.rs:59:22:
attempt to add with overflow

$ printf '\ta\tb\tc\n' | fmt -q -T 9223372036854775808
thread 'main' panicked at src/uu/fmt/src/linebreak.rs:32:28:
attempt to multiply with overflow

Fix

  • Add const MAX_TAB_WIDTH: usize = 2500 (mirrors the existing MAX_WIDTH limit).
  • After parsing the tab-width string, check against MAX_TAB_WIDTH and return a new TabWidthOutOfRange error if exceeded.
  • The error message matches the WidthOutOfRange pattern: "invalid tab width: '<N>': Numerical result out of range".
  • Translation strings added to en-US.ftl and fr-FR.ftl.

Tests

Two new integration tests:

  • test_fmt_tab_width_too_big — verifies 2501 is rejected with exit code 1 and the expected message.
  • test_fmt_tab_width_at_max — verifies 2500 is accepted.

Fixes #14460

🤖 Generated with Claude Code

`--tab-width`/`-T` had no upper bound: any usize value was accepted and
flowed directly into arithmetic in linebreak.rs and parasplit.rs.
Values near usize::MAX caused panics (add/subtract/multiply overflow)
or an `attempt to subtract with overflow` at multiple call sites.

Add `MAX_TAB_WIDTH = 2500` (matching `MAX_WIDTH`) and validate the
parsed value before constructing `FmtOptions`. A new `TabWidthOutOfRange`
error variant mirrors the existing `WidthOutOfRange` path and produces
the expected "Numerical result out of range" diagnostic.

Fixes uutils#14460
Copilot AI lite review requested due to automatic review settings September 18, 2026 09:58

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

Comment thread src/uu/fmt/src/fmt.rs
}

const MAX_WIDTH: usize = 2500;
const MAX_TAB_WIDTH: usize = 2500;

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.

We don't need two names for the same value: 2500.

@oech3

oech3 commented Sep 18, 2026

Copy link
Copy Markdown
Contributor

As I noted at #14460 (comment) , this is not part of GNU.
So we can simply remove this feature. If this is really important, we should request this to GNU.

fmt-error-invalid-width = invalid width: {$width}
fmt-error-width-out-of-range = invalid width: '{$width}': Numerical result out of range
fmt-error-invalid-tabwidth = Invalid TABWIDTH specification: {$tabwidth}
fmt-error-tabwidth-out-of-range = invalid tab width: '{$tabwidth}': Numerical result out of range

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.

We don't need two aliases for the same output: invalid width: '{$key}': Numerical result out of range

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. It is slightly different. But I think adding different message is overkill.

Comment thread src/uu/fmt/src/fmt.rs
#[error("{}", translate!("fmt-error-invalid-tabwidth", "tabwidth" => .0.quote()))]
InvalidTabWidth(String),
#[error("{}", translate!("fmt-error-tabwidth-out-of-range", "tabwidth" => .0))]
TabWidthOutOfRange(usize),

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.

Same. Not required.

Comment thread src/uu/fmt/src/fmt.rs
.max(1);
if tabwidth > MAX_TAB_WIDTH {
return Err(FmtError::TabWidthOutOfRange(tabwidth).into());
}

@oech3 oech3 Sep 18, 2026

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.

I would use .filter() and .ok_or_else() at 1st chain.

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.

Can we use let tabwidth @ .. MAX_WIDTH = ... else {?

@sylvestre

Copy link
Copy Markdown
Contributor

As I noted at #14460 (comment) , this is not part of GNU. So we can simply remove this feature. If this is really important, we should request this to GNU.

I am fine keeping it for now

@github-actions

github-actions Bot commented Sep 18, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/date/date-locale-hour (fails in this run but passes in the 'main' branch)

Copilot AI review requested due to automatic review settings September 19, 2026 18:25

Copilot AI left a comment

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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

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.

fmt: --tab-width/-T has no upper bound — arithmetic overflow aborts at multiple sites (exit 134)

4 participants