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 a8e826124b Prevent repeat slice length overflow (#9819)
a8e826124b is described below

commit a8e826124be6bcd842167292fcb3a68f1e43bba4
Author: Andrew Lamb <[email protected]>
AuthorDate: Sat Apr 25 11:19:49 2026 -0400

    Prevent repeat slice length overflow (#9819)
    
    # Which issue does this PR close?
    
    - None.
    
    # Rationale for this change
    
    MutableBuffer repeated slices used unchecked usize arithmetic when
    calculating the number of bytes to reserve. In optimized builds, very
    large repeat counts could wrap the capacity calculation before copying
    repeated bytes.
    
    # What changes are included in this PR?
    
    This adds checked arithmetic for repeated slice byte length validation
    before reserving capacity and copying repeated data.
    
    # Are these changes tested?
    
    Yes. This adds regression coverage for overflowing repeated slice length
    calculations.
    
    # Are there any user-facing changes?
    
    Invalid repeat counts whose requested byte length cannot be represented
    without overflow now panic consistently. There are no API changes.
---
 arrow-buffer/src/buffer/mutable.rs | 23 ++++++++++++++++++++++-
 1 file changed, 22 insertions(+), 1 deletion(-)

diff --git a/arrow-buffer/src/buffer/mutable.rs 
b/arrow-buffer/src/buffer/mutable.rs
index 07ef965cb0..f4e532029b 100644
--- a/arrow-buffer/src/buffer/mutable.rs
+++ b/arrow-buffer/src/buffer/mutable.rs
@@ -284,9 +284,15 @@ impl MutableBuffer {
         }
 
         let bytes_to_repeat = size_of_val(slice_to_repeat);
+        let repeated_bytes = repeat_count
+            .checked_mul(bytes_to_repeat)
+            .expect("repeated slice byte length overflow");
+        self.len
+            .checked_add(repeated_bytes)
+            .expect("mutable buffer length overflow");
 
         // Ensure capacity
-        self.reserve(repeat_count * bytes_to_repeat);
+        self.reserve(repeated_bytes);
 
         // Save the length before we do all the copies to know where to start 
from
         let length_before = self.len;
@@ -1474,6 +1480,21 @@ mod tests {
         test_repeat_count(0, &[1i32, 2, 3]);
     }
 
+    #[test]
+    #[should_panic(expected = "repeated slice byte length overflow")]
+    fn test_repeat_slice_count_multiply_overflow() {
+        let mut buffer = MutableBuffer::new(0);
+        buffer.repeat_slice_n_times(&[0_u64], usize::MAX / 
mem::size_of::<u64>() + 1);
+    }
+
+    #[test]
+    #[should_panic(expected = "mutable buffer length overflow")]
+    fn test_repeat_slice_count_len_overflow() {
+        let mut buffer = MutableBuffer::new(0);
+        buffer.push(0_u8);
+        buffer.repeat_slice_n_times(&[0_u8], usize::MAX);
+    }
+
     #[test]
     fn test_small_repeats_counts() {
         // test any special implementation for small repeat counts

Reply via email to