uutils / uutils/coreutils

numfmt panics (index out of bounds) on a very large `--to=si`/`--to=iec` value

Open Beginner friendly
#12,581 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

U - numfmt
Dominant language
Rust
Stars
24.1k
Forks
2k
Avg merge
1d 5h
Merged PRs (30d)
365

Description

Summary

numfmt --to=si (and --to=iec) panics with an index-out-of-bounds when the
input value falls in the top supported decade and rounding bumps the scaled
value back up to the next base. consider_suffix computes a suffix index i
that can be 10, then indexes the 10-element suffixes array (suffixes[i])
on the rounding-overflow branch — suffixes[10] is out of bounds.

GNU numfmt handles the same input cleanly: it prints
numfmt: value too large to be converted: '<n>' and exits 2.

Steps to reproduce

$ numfmt --to=si 999500000000000000000000000000000
thread 'main' panicked at src/uu/numfmt/src/format.rs:536:33:
index out of bounds: the len is 10 but the index is 10
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Aborted (core dumped)
$ echo $?
134

numfmt --to=si 1000000000000000000000000000000000 (10³³) panics the same way.
The --to=iec path has the same shape (with bases[10] = 1024¹⁰).

Expected behavior

Match GNU: report the value as too large and exit non-zero, without panicking.

$ /usr/bin/numfmt --to=si 999500000000000000000000000000000
/usr/bin/numfmt: value too large to be converted: ‘999500000000000000000000000000000’
$ echo $?
2

(numfmt already has the right error for even larger inputs — e.g.
numfmt --to=si 9995…e33 returns Number is too big and unsupported, exit 2.
This bug is the narrow band just below that, where it aborts instead.)

Actual behavior

The process panics and aborts (exit 134) with an index-out-of-bounds, instead of
a clean error.

Root cause

consider_suffix in src/uu/numfmt/src/format.rs:

let suffixes = [K, M, G, T, P, E, Z, Y, R, Q];   // length 10, valid indices 0..=9

let i = match abs_n {
    ...
    _ if abs_n < bases[10]          => 9,
    _ if abs_n < bases[10] * 1000.0 => 10,        // i can be 10
    _ => return Err(translate!("numfmt-error-number-too-big")),
};

let v = /* n scaled by bases[i], rounded */;

if v.abs() >= bases[1] {
    Ok((v / bases[1], Some((suffixes[i], with_i))))   // i == 10 -> suffixes[10] -> OOB panic
} else {
    Ok((v, Some((suffixes[i - 1], with_i))))          // i == 10 -> suffixes[9] -> OK
}

When abs_n ∈ [bases[10], bases[10]·1000) the index is 10. Normally the value
then scales below bases[1] and the else branch (suffixes[i - 1] = suffixes[9],
the largest suffix) is taken. But when rounding lifts v to ≥ bases[1]
(e.g. n / bases[10] rounds up to 1000), the then branch runs suffixes[i]
with i == 10 → panic.

A fix should treat i == 10 in the rounding-overflow branch as "value too large"
(the same numfmt-error-number-too-big path the next match arm already uses),
since there is no SI/IEC suffix beyond the top base.

Environment

  • uutils coreutils: numfmt (uutils coreutils) 0.9.0 (latest main, commit 0011d54, 2026-06-03; numfmt/format.rs unchanged across recent commits)
  • rustc: 1.89.0
  • Reference: GNU coreutils 8.30

Found by our static analysis tooling.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in src/uu/numfmt/src/format.rs at consider_suffix and reproduce the issue with the provided --to=si and --to=iec commands. Trace the rounding-overflow branch for i == 10 and verify that the completed change reports numfmt-error-number-too-big, exits non-zero, and no longer panics for the boundary inputs.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
cli
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.