Skip to content

od, nl: match GNU on -w suffixes and huge -l values - #15564

Merged
sylvestre merged 4 commits into
uutils:mainfrom
fixfon:fix/15551-od-width-nl-join-blank
Oct 22, 2026
Merged

sylvestre merged 4 commits into
uutils:mainfrom
fixfon:fix/15551-od-width-nl-join-blank

Conversation

@fixfon

@fixfon fixfon commented Oct 21, 2026

Copy link
Copy Markdown
Contributor

Two small option-parsing fixes, one commit each.

od -w went through the same parser as -N and -j, so it took size suffixes (1K, 1b), 0x hex, and read a leading zero as octal. GNU only takes a plain decimal number there. -w now has its own small parser that accepts digits only and reuses the existing error messages. As a side effect -w010 is now 10 instead of 8, and -w08 is accepted, both matching GNU. The bare -w form and the huge-width path are untouched. The --width=1Y case in test_od_invalid_bytes expected the old behavior, so I moved that check into the new tests.

nl -l rejected anything above u64::MAX. GNU accepts it, since it only caps how many blank lines get joined. A value that is all digits and too large now saturates to u64::MAX. -v, -i and -w still reject large values, same as GNU.

Added tests in test_od.rs and test_nl.rs plus a unit test for the new parser. Three of them fail on main and pass with this change. I also ran 24 cases against the GNU 9.12 binaries on macOS, and the exit code and output match on all of them.

Left out on purpose, since main behaves the same way: od -w+4, od -w' 4' and nl -l ' 3' are accepted by GNU but rejected here. The panic on a huge -w value belongs to #12885.

Fixes #15551

-w takes a plain decimal number. It was parsed like a size, so 1K, 2b
or 0x8 were accepted and a leading zero meant octal.
A number too large for u64 now saturates instead of being rejected.
-v, -i and -w still reject values that are too large.
Comment thread src/uu/od/src/parse_nrofbytes.rs Outdated

/// Parses a plain decimal number, as `-w` takes: no radix prefix (a leading
/// zero is not octal) and no multiplier suffix.
pub fn parse_plain_number(s: &str) -> Result<u64, ParseSizeError> {

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.

seems like a too generic function name, maybe parse_width?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair point, it was too generic for what it does. Renamed it to parse_width.

Comment thread tests/by-util/test_od.rs Outdated
@@ -1335,14 +1335,12 @@ fn test_od_invalid_bytes() {
const BIG_SIZE: &str = "1Y";

// NOTE:

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.

do we still need this NOTE now that --width is gone from the list?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, with --width out of that list the note no longer says anything useful. Removed it.

Rename parse_plain_number to parse_width, drop the test_od note that
no longer applies now that --width is out of the list, and stop piping
stdin into the nl test whose options are rejected before any input is
read (the write raced with nl exiting and hit a broken pipe on
i686-musl).
…arguments

These commands exit on the bad argument without reading stdin, so writing
to the child's stdin raced with its exit and could fail with a broken
pipe.
@sylvestre
sylvestre merged commit 29550e9 into uutils:main Oct 22, 2026
103 of 104 checks passed
@sylvestre

Copy link
Copy Markdown
Contributor

Thanks for your PR

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.

Two small number-parsing differences: od -w accepts a size suffix, nl -l rejects huge values

2 participants