From c0674cb8923dcdc5717b3209fcf207e06729824b Mon Sep 17 00:00:00 2001 From: Matteo Oldani Date: Fri, 3 Jul 2026 12:00:24 +0000 Subject: [PATCH] Fix allocator capacity bounds checking and tracking in Buf32 --- tendril/src/buf32.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/tendril/src/buf32.rs b/tendril/src/buf32.rs index 507c52b7..cacd8027 100644 --- a/tendril/src/buf32.rs +++ b/tendril/src/buf32.rs @@ -30,6 +30,18 @@ fn bytes_to_vec_capacity(x: u32) -> usize { 1 + ((x - 1) / header) } +#[inline(always)] +fn vec_capacity_to_bytes(vec_cap: usize) -> u32 { + // The first H element is consumed by the header metadata, + // the remaining elements are available for the string payload. + let actual_cap_bytes = (vec_cap - 1) * mem::size_of::(); + + if actual_cap_bytes > u32::MAX as usize { + panic!("{}", OFLOW); + } + actual_cap_bytes as u32 +} + impl Buf32 { #[inline] pub unsafe fn with_capacity(mut cap: u32, h: H) -> Buf32 { @@ -38,6 +50,8 @@ impl Buf32 { } let mut vec = Vec::::with_capacity(bytes_to_vec_capacity::(cap)); + cap = vec_capacity_to_bytes::(vec.capacity()); + let ptr = vec.as_mut_ptr(); mem::forget(vec); ptr::write(ptr, h); @@ -82,7 +96,8 @@ impl Buf32 { let mut vec = Vec::from_raw_parts(self.ptr, 0, bytes_to_vec_capacity::(self.cap)); vec.reserve_exact(bytes_to_vec_capacity::(new_cap)); self.ptr = vec.as_mut_ptr(); - self.cap = new_cap; + self.cap = vec_capacity_to_bytes::(vec.capacity()); + mem::forget(vec); } }