split: keep a suffix start at the top of the range from overflowing - #14297
Open
arbelonson-source wants to merge 2 commits into
Open
split: keep a suffix start at the top of the range from overflowing#14297arbelonson-source wants to merge 2 commits into
arbelonson-source wants to merge 2 commits into
Conversation
`split` works out how wide the suffixes need to be from the start value
plus the number of chunks. Either of those on its own can be as large as
the type allows, so their sum is not always a value the type can hold:
$ split -n 5 --numeric-suffixes=18446744073709551615 /dev/null
thread 'main' panicked at src/uu/split/src/filenames.rs:202:36:
attempt to add with overflow
$ split -n 5 --hex-suffixes=ffffffffffffffff /dev/null
thread 'main' panicked at src/uu/split/src/filenames.rs:202:36:
attempt to add with overflow
With overflow checks off the add wraps instead, and the width computed
from the wrapped sum is too small.
Add in a type with room for the sum. The width then comes out right, and
the value is refused the way any other too-wide start is:
$ split -n 5 --numeric-suffixes=18446744073709551615 /dev/null
split: the suffix length needs to be at least 20
Fixes uutils#13749.
|
GNU testsuite comparison: |
CI failed this test on i686 (and i686 windows): the start value `18446744073709551615` is `u64::MAX`, which does not fit in a 32-bit `usize`, so `--numeric-suffixes` rejects it at the parse step there with a different message than the overflow-guard one this test checks. The overflow this test exists for can only occur once `start` itself reaches `u64::MAX`, which requires a 64-bit `usize` to hold in the first place -- so on a 32-bit target there is nothing here left to overflow, and the test doesn't apply.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #13749.
splitworks out how wide the suffixes need to be from the start value plus the number of chunks. Either of those on its own can be as large as the type allows, so their sum is not always a value the type can hold:With overflow checks off the add wraps instead, and the width computed from the wrapped sum is too small. Adding in
u128leaves room for the sum, so the width comes out right and the value is refused the way any other too-wide start already is:@leeewee's report also names a third route to the same add — a huge
-nwith a nonzero start — and that one stops panicking too.Scope
This is the panic only. Two neighbouring differences are left alone, and neither is touched by the change:
numerical suffix start value is too large for the suffix length, we saythe suffix length needs to be at least N.split -n 5 --numeric-suffixes=99999already showed that onmain, with no overflow involved.-a, GNU carries the suffix pastu64(x18446744073709551616, and for hex it walks the ASCII pastfintoxfffffffffffffff:); ourFixedWidthNumberisu64-backed and stops withoutput file suffixes exhausted. Before this change that case panicked, so it is an improvement rather than a match.Testing
-n/-l/-b/-C/-n l/N/-n r/Ncrossed with--numeric-suffixes/--hex-suffixesat starts from 0 to 99999,-afrom 1 to 10,-d,-xand--additional-suffix, comparing stdout, stderr, exit code and the resulting file names: 509 identical, 0 changed. Nothing in range moves.test_suffix_start_at_the_top_of_the_range, verified to fail onmain.cargo test --features split --test tests -- test_split: 141 passed, 0 failed (140 pre-existing, 1 new);cargo test -p uu_split: 23 passed.cargo fmt --checkandcargo clippy -p uu_split --all-targets -- -D warnings: clean.Disclosure
Prepared with AI assistance (Claude Opus 5, via Claude Code), per the AI policy in CONTRIBUTING.md. GNU's behaviour was established by running the installed GNU binary as a black box; I did not read GNU coreutils source. All testing was run locally.