From b94e034935656e5691ec6830b0590ee82330b61f 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) # Which issue does this PR close? - None. # Rationale for this change 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. # What changes are included in this PR? This adds checked arithmetic for BitChunks bounds validation # Are these changes tested? Yes. This adds regression coverage for overflowing bit offset plus length validation. # Are there any user-facing changes? 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 | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/arrow-buffer/src/util/bit_chunk_iterator.rs b/arrow-buffer/src/util/bit_chunk_iterator.rs index 8c7ec5e9a8f6..6655c397ebbd 100644 --- a/arrow-buffer/src/util/bit_chunk_iterator.rs +++ b/arrow-buffer/src/util/bit_chunk_iterator.rs @@ -220,10 +220,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(), - "offset + len out of bounds" - ); + let end = offset.checked_add(len).expect("offset + len out of bounds"); + assert!(ceil(end, 8) <= buffer.len(), "offset + len out of bounds"); let byte_offset = offset / 8; let bit_offset = offset % 8; @@ -550,6 +548,13 @@ mod tests { buffer.bit_chunks(1, ALLOC_SIZE * 8); } + #[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() {