Skip to content

fix(read): handle dynamic-buffer max_size without throwing (#318)#340

Merged
mvandeberg merged 1 commit into
cppalliance:develop-2from
mvandeberg:pr/318-read-until-max-size
Jun 26, 2026
Merged

fix(read): handle dynamic-buffer max_size without throwing (#318)#340
mvandeberg merged 1 commit into
cppalliance:develop-2from
mvandeberg:pr/318-read-until-max-size

Conversation

@mvandeberg

Copy link
Copy Markdown
Contributor

The read dynamic-buffer overloads passed the (grown) amount straight to dynbuf.prepare(), so when it exceeded the remaining capacity (e.g. the default initial_amount of 2048 into a bounded buffer) prepare() threw std::invalid_argument / std::length_error. This was inconsistent with read_until, which already clamps.

Clamp the prepared amount to max_size() - size() and treat reaching max_size() as a successful completion. The existing eof-as-success semantics are unchanged, and read_until keeps returning error::not_found at max_size().

The clamp targets the contract that prepare(n) accepts any n with size() + n <= max_size(): string/vector grow and circular wraps to honor it. A fixed-capacity buffer may, but need not, compact; a non-compacting flat_dynamic_buffer reused after a partial consume has capacity() < max_size() - size(), so prepare throws. This is documented as a limitation — such buffers must be passed without a consumed prefix. Clamping to capacity() instead is not viable: it spins growable buffers.

Also floor the prepared amount to 1 so initial_amount == 0 cannot spin, and factor the clamp into detail::read_prepare_amount so the two overloads cannot drift.

Tests cover bounded string/circular/flat buffers, the flat consumed-prefix throw, and buffer contents.

Closes #318

…ce#318)

The read dynamic-buffer overloads passed the (grown) amount straight to
dynbuf.prepare(), so when it exceeded the remaining capacity (e.g. the
default initial_amount of 2048 into a bounded buffer) prepare() threw
std::invalid_argument / std::length_error. This was inconsistent with
read_until, which already clamps.

Clamp the prepared amount to max_size() - size() and treat reaching
max_size() as a successful completion. The existing eof-as-success
semantics are unchanged, and read_until keeps returning error::not_found
at max_size().

The clamp targets the contract that prepare(n) accepts any n with
size() + n <= max_size(): string/vector grow and circular wraps to honor
it. A fixed-capacity buffer may, but need not, compact; a non-compacting
flat_dynamic_buffer reused after a partial consume has
capacity() < max_size() - size(), so prepare throws. This is documented
as a limitation — such buffers must be passed without a consumed prefix.
Clamping to capacity() instead is not viable: it spins growable buffers.

Also floor the prepared amount to 1 so initial_amount == 0 cannot spin,
and factor the clamp into detail::read_prepare_amount so the two
overloads cannot drift.

Tests cover bounded string/circular/flat buffers, the flat consumed-prefix
throw, and buffer contents.
@cppalliance-bot

Copy link
Copy Markdown

An automated preview of the documentation is available at https://340.capy.prtest3.cppalliance.org/index.html

If more commits are pushed to the pull request, the docs will rebuild at the same URL.

2026-06-25 20:28:05 UTC

@codecov

codecov Bot commented Jun 25, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
⚠️ Please upload report for BASE (develop-2@1559c4f). Learn more about missing BASE report.

Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff              @@
##             develop-2     #340   +/-   ##
============================================
  Coverage             ?   98.39%           
============================================
  Files                ?       83           
  Lines                ?     4237           
  Branches             ?        0           
============================================
  Hits                 ?     4169           
  Misses               ?       68           
  Partials             ?        0           
Flag Coverage Δ
linux 98.39% <ø> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 1559c4f...902a66f. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mvandeberg mvandeberg merged commit 0d510ab into cppalliance:develop-2 Jun 26, 2026
37 checks passed
@github-project-automation github-project-automation Bot moved this from Backlog to Done in Beast2 Jun 26, 2026
@mvandeberg mvandeberg deleted the pr/318-read-until-max-size branch June 26, 2026 20:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants