From 8aa4b5b76707001da8a23e9c032155106b053f24 Mon Sep 17 00:00:00 2001 From: Andrew Lamb Date: Sat, 25 Apr 2026 11:19:17 -0400 Subject: [PATCH] Prevent BitChunks length overflow (#9818) - None. BitChunks used unchecked usize arithmetic when validating bit offset plus length. In optimized builds, very large lengths could wrap this bounds check before constructing the iterator state. This adds checked arithmetic for BitChunks bounds validation Yes. This adds regression coverage for overflowing bit offset plus length validation. Invalid BitChunks inputs whose offset and length cannot be represented without overflow now panic consistently. There are no API changes. --- arrow-buffer/src/util/bit_chunk_iterator.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/arrow-buffer/src/util/bit_chunk_iterator.rs b/arrow-buffer/src/util/bit_chunk_iterator.rs index ea8e8f472ace..4ac14219153a 100644 --- a/arrow-buffer/src/util/bit_chunk_iterator.rs +++ b/arrow-buffer/src/util/bit_chunk_iterator.rs @@ -221,7 +221,8 @@ pub struct BitChunks<'a> { impl<'a> BitChunks<'a> { /// Create a new [`BitChunks`] from a byte array, and an offset and length in bits pub fn new(buffer: &'a [u8], offset: usize, len: usize) -> Self { - assert!(ceil(offset + len, 8) <= buffer.len() * 8); + let end = offset.checked_add(len).expect("offset + len out of bounds"); + assert!(ceil(end, 8) <= buffer.len() * 8); let byte_offset = offset / 8; let bit_offset = offset % 8; @@ -476,6 +477,13 @@ mod tests { assert_eq!(0x7F, bitchunks.remainder_bits()); } + #[test] + #[should_panic(expected = "offset + len out of bounds")] + fn test_out_of_bound_should_panic_when_offset_and_length_overflow() { + let buffer = Buffer::from(vec![0xFF_u8; 8]); + buffer.bit_chunks(1, usize::MAX); + } + #[test] #[allow(clippy::assertions_on_constants)] fn test_unaligned_bit_chunk_iterator() {