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() {

Reply via email to