This is an automated email from the ASF dual-hosted git repository.
alamb pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 5fae47e957 Prevent BitChunks length overflow (#9818)
5fae47e957 is described below
commit 5fae47e95702b76cd449b54d9a1cb6a4158cff7f
Author: Andrew Lamb <[email protected]>
AuthorDate: Sat Apr 25 11:19:17 2026 -0400
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 8c7ec5e9a8..6655c397eb 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() {