Skip to content

printf: panics on a numeric field width above 65535 (%65536d) #13850

Description

@sylvestre

printf panics instead of printing when a numeric conversion is given a field width above 65535:

$ printf '%65536d' 5
thread 'main' panicked at src/uucore/src/lib/features/format/num_format.rs:781:17:
Formatting argument out of range
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
$ echo $?
101

GNU prints the padded field and exits 0:

$ /usr/bin/printf '%65536d' 5 | wc -c
65536

The boundary is exactly u16::MAX: %65535d works, %65536d panics. It affects numeric
conversions (%d, %f, ...) but not %s, so %65536s is fine.

The cause is that the width is passed straight to Rust's formatting machinery, which only
accepts a width that fits in a u16. The fix is to stop relying on format! for the padding
once the width exceeds that, and emit the padding directly.

Where

src/uucore/src/lib/features/format/num_format.rs, in the NumberAlignment handling — the
write!(writer, "{s:>width$}", ...) / write!(writer, "{sign_indicator}{s:>remaining_width$}")
calls (around line 781 on current main).

Related, but not the same code

The same "Formatting argument out of range" message is reported in #12593 (%111111c) and
#12900 (%-101727s), which both panic in src/uucore/src/lib/features/format/spec.rs. This one
is a separate site in num_format.rs and still reproduces with those unfixed. They share a root
cause, so whoever fixes one may want to look at all three.

Why this is a good first issue

The reproducer is a single command, the failing line is known, and the fix is local to one
function. A regression test belongs in tests/by-util/test_printf.rs.

Found with coreutils 0.10.0 (multi-call binary) at 282b8b4, compared against GNU coreutils
9.11.64.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions