Skip to content

dd: derive the count_bytes read budget from bytes read#13435

Open
relative23 wants to merge 7 commits into
uutils:mainfrom
relative23:dd-count-bytes-loop-bsize
Open

dd: derive the count_bytes read budget from bytes read#13435
relative23 wants to merge 7 commits into
uutils:mainfrom
relative23:dd-count-bytes-loop-bsize

Conversation

@relative23

@relative23 relative23 commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Fixes #13434.

calc_loop_bsize used bytes written to calculate the remaining input budget for count=N iflag=count_bytes. Expanding conversions could make the subtraction underflow: debug builds panicked, while release builds read 1,024 input bytes for count=1000.

Use rstat.bytes_total with saturating subtraction. The regression test verifies that only the first 1,000 input bytes are converted.

Validation

  • cargo test -p uu_dd
  • dd integration tests
  • CodSpeed reports no performance change

@relative23
relative23 force-pushed the dd-count-bytes-loop-bsize branch from 4d451be to 136f5a9 Compare July 17, 2026 19:17
calc_loop_bsize computed the remaining byte budget for
count=N iflag=count_bytes from the bytes written so far, while
below_count_limit gates the copy loop on bytes read. A conversion that
writes more than it reads (conv=block record expansion, conv=sync
padding of partial reads) pushes the written total past the limit while
the read total is still below it, and the u128 subtraction underflowed:
a panic in debug builds ('attempt to subtract with overflow' in
calc_loop_bsize), and a wrapped huge value in release builds that
unlocked a full-sized read on every following iteration, silently
overshooting the count limit.

Derive the remaining budget from the bytes read instead, matching
below_count_limit and the documented semantics of count_bytes
(saturating, so an inconsistency degrades to a zero-sized read instead
of wrapping), and drop the now-unused WriteStat parameter.
@relative23
relative23 force-pushed the dd-count-bytes-loop-bsize branch from 136f5a9 to c2c13db Compare July 18, 2026 13:00
@codspeed-hq

codspeed-hq Bot commented Jul 20, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 339 untouched benchmarks
⏩ 46 skipped benchmarks1


Comparing relative23:dd-count-bytes-loop-bsize (746146d) with main (20bc45c)

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.

@github-actions

github-actions Bot commented Jul 20, 2026

Copy link
Copy Markdown

GNU testsuite comparison:

Skipping an intermittent issue tests/misc/tty-eof (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/pr/bounded-memory (passes in this run but fails in the 'main' branch)
Skipping an intermittent issue tests/tail/tail-n0f (passes in this run but fails in the 'main' branch)
Congrats! The gnu test tests/sort/sort-NaN-infloop is no longer failing!
Note: The gnu test tests/printf/printf-surprise is now being skipped but was previously passing.
Congrats! The gnu test tests/basenc/bounded-memory is now passing!

Comment thread src/uu/dd/src/dd.rs Outdated
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.

dd: count=N iflag=count_bytes underflows when a conversion writes more than N bytes (debug panic, count limit bypassed in release)

2 participants