Skip to content

numfmt: reject a leading + and scientific notation to match GNU - #13899

Open
AlejandroCoronadoN wants to merge 1 commit into
uutils:mainfrom
AlejandroCoronadoN:fix-numfmt-scientific-plus
Open

numfmt: reject a leading + and scientific notation to match GNU#13899
AlejandroCoronadoN wants to merge 1 commit into
uutils:mainfrom
AlejandroCoronadoN:fix-numfmt-scientific-plus

Conversation

@AlejandroCoronadoN

Copy link
Copy Markdown

Problem

numfmt silently accepts inputs that GNU rejects, and prints a wrong value:

$ printf '1e-3\n' | numfmt --from=auto   # prints "1"  (GNU: invalid suffix in input)
$ printf '1e+3\n' | numfmt --from=auto   # prints "1000"
$ printf '+5\n'   | numfmt --from=auto   # prints "5"   (GNU: invalid number)

Rust's i128/f64 parsers accept a leading + and scientific notation, so
these slip through parse_number_part. The E (Exa) suffix is not affected,
because the suffix is stripped before the number is parsed.

Fix

In parse_number_part, reject a leading + and any e/E in the number part,
using GNU's two distinct messages (invalid number for the sign, invalid suffix in input for the exponent).

Verification

Compared against GNU coreutils (gnumfmt) over a matrix of 20 inputs: every
previously-wrong case now matches GNU's exit code (2) and message, and valid
inputs (1K, 2.5M, 100Ki, 1P, 3.5G, -42, ...) are unchanged.

$ printf '1e-3\n' | numfmt --from=auto
numfmt: invalid suffix in input: '1e-3'
$ printf '+5\n' | numfmt --from=auto
numfmt: invalid number: '+5'

Added a regression test; the full test_numfmt suite passes and cargo fmt /
cargo clippy are clean.

@sylvestre
sylvestre force-pushed the fix-numfmt-scientific-plus branch from 17bd101 to b1e7b46 Compare August 13, 2026 07:16
@codspeed-hq

codspeed-hq Bot commented Aug 13, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 347 untouched benchmarks
🆕 10 new benchmarks
⏩ 46 skipped benchmarks1

Performance Changes

Mode Benchmark BASE HEAD Efficiency
🆕 Memory ptx_input_references_short_lines[100000] N/A 222.2 MB N/A
🆕 Memory ptx_long_lines[100] N/A 29.5 MB N/A
🆕 Memory ptx_short_lines[100000] N/A 240.1 MB N/A
🆕 Memory ptx_input_references_long_lines[1000] N/A 29.1 MB N/A
🆕 Memory ptx_tex[10000] N/A 20.6 MB N/A
🆕 Simulation ptx_input_references_short_lines[100000] N/A 16.2 s N/A
🆕 Simulation ptx_long_lines[100] N/A 1.7 s N/A
🆕 Simulation ptx_short_lines[100000] N/A 14 s N/A
🆕 Simulation ptx_input_references_long_lines[1000] N/A 2 s N/A
🆕 Simulation ptx_tex[10000] N/A 2.9 s N/A

Comparing AlejandroCoronadoN:fix-numfmt-scientific-plus (721a00a) with main (66cf72b)2

Open in CodSpeed

Footnotes

  1. 46 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (e6561b5) during the generation of this report, so 66cf72b was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

GNU numfmt rejects a number with a leading '+' sign ("+5") as an invalid
number, and rejects scientific notation ("1e-3") as an invalid suffix in
input. Rust's i128 and f64 parsers accept both, so numfmt silently accepted
them and printed a wrong value with exit 0. Reject them in parse_number_part,
mirroring GNU's two distinct diagnostics.
@sylvestre
sylvestre force-pushed the fix-numfmt-scientific-plus branch from b1e7b46 to 721a00a Compare August 13, 2026 08:13
@github-actions

Copy link
Copy Markdown

GNU testsuite comparison:

Skip an intermittent issue tests/tail/inotify-dir-recreate (fails in this run but passes in the 'main' branch)
Congrats! The gnu test tests/cat/splice is no longer failing!
Congrats! The gnu test tests/ls/stat-free-symlinks is no longer failing!
Congrats! The gnu test tests/mv/dir2dir is no longer failing!
Congrats! The gnu test tests/nl/multibyte is no longer failing!
Congrats! The gnu test tests/printf/printf-surprise is now passing!

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.

1 participant