Skip to content

Fix capacity-overflow panic on untrusted counts in helpers::count - #369

Open
gaoflow wants to merge 1 commit into
jam1garner:masterfrom
gaoflow:fix-count-vec-u8-reserve-overflow
Open

Fix capacity-overflow panic on untrusted counts in helpers::count#369
gaoflow wants to merge 1 commit into
jam1garner:masterfrom
gaoflow:fix-count-vec-u8-reserve-overflow

Conversation

@gaoflow

@gaoflow gaoflow commented Jul 31, 2026

Copy link
Copy Markdown

helpers::count reserves Vec<u8> capacity from the input-driven count, so a
count of u64::MAX (8 bytes of 0xFF) panics with "capacity overflow" before
any byte is read. Every #[br(count = N)] Vec<u8> field routes through this
path.

#365 hardened punctuated against this class ("Let the Vec grow as elements
are successfully read, like helpers::count"), but helpers::count's own
Vec<u8> fast path is the un-hardened sibling. The reserve is dropped so the
Vec grows as bytes are read, the same std exponential strategy read_vec_fast_int
already uses for integer vectors.

#[derive(BinRead)]
#[br(big)]
struct Test { len: u64, #[br(count = len)] data: Vec<u8> }
Test::read(&mut Cursor::new([0xff; 8]))

panics before this change (debug and release); after it, Err(not enough bytes).

Regression test covers the huge-count case, short input, count=0, and a valid
1 MiB read.

The Vec<u8> fast path reserved the input-driven count before reading any
byte, so a count of u64::MAX (8 bytes of 0xFF) panicked with "capacity
overflow" in Vec::reserve_exact. Drop the reserve and let read_to_end grow
the Vec as bytes are read, matching the chunked pattern used by
read_vec_fast_int and the hardening applied to punctuated in jam1garner#365.
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.

1 participant