This is an automated email from the ASF dual-hosted git repository.

alamb pushed a commit to branch 57_maintenance
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/57_maintenance by this push:
     new 45a5665c04 [57_maintenance] Prevent Rows row index overflow (#9817) 
(#9922)
45a5665c04 is described below

commit 45a5665c04b9228d72f6a826d415c5181e7104bf
Author: Andrew Lamb <[email protected]>
AuthorDate: Wed May 6 10:33:30 2026 -0400

    [57_maintenance] Prevent Rows row index overflow (#9817) (#9922)
    
    - Part of https://github.com/apache/arrow-rs/issues/9858
    - Fixes https://github.com/apache/arrow-rs/issues/9901 in 57.x releases
    
    This PR:
    - Backports https://github.com/apache/arrow-rs/pull/9817 from @alamb to
    the `57_maintenance` line
    
    Note: `Rows::row_len` and `Rows::lengths` are not present on the
    `57_maintenance` line, so this backport applies the checked row index
    validation to `Rows::row` and includes the `row_unchecked` safety
    documentation update from the original PR.
---
 arrow-row/src/lib.rs | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/arrow-row/src/lib.rs b/arrow-row/src/lib.rs
index 4cafbc2748..01de7f7825 100644
--- a/arrow-row/src/lib.rs
+++ b/arrow-row/src/lib.rs
@@ -1132,14 +1132,20 @@ impl Rows {
 
     /// Returns the row at index `row`
     pub fn row(&self, row: usize) -> Row<'_> {
-        assert!(row + 1 < self.offsets.len());
+        self.checked_row_end(row);
         unsafe { self.row_unchecked(row) }
     }
 
+    fn checked_row_end(&self, row: usize) -> usize {
+        row.checked_add(1)
+            .filter(|end| *end < self.offsets.len())
+            .expect("row index out of bounds")
+    }
+
     /// Returns the row at `index` without bounds checking
     ///
     /// # Safety
-    /// Caller must ensure that `index` is less than the number of offsets 
(#rows + 1)
+    /// Caller must ensure that `index + 1` is less than the number of offsets 
(#rows + 1)
     pub unsafe fn row_unchecked(&self, index: usize) -> Row<'_> {
         let end = unsafe { self.offsets.get_unchecked(index + 1) };
         let start = unsafe { self.offsets.get_unchecked(index) };
@@ -4283,4 +4289,13 @@ mod tests {
             "{empty_rows_size_with_preallocate_data} should be larger than 
{empty_rows_size_without_preallocate}"
         );
     }
+
+    #[test]
+    #[should_panic(expected = "row index out of bounds")]
+    fn row_should_panic_on_overflowing_index() {
+        let rows = RowConverter::new(vec![SortField::new(DataType::Int32)])
+            .unwrap()
+            .empty_rows(0, 0);
+        rows.row(usize::MAX);
+    }
 }

Reply via email to