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

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-11318-862b1e065b602400784268df9ded5d0a18710eed
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git

commit 7c88505f9e3bb5b5275aa2838e7ef0757962964b
Author: pawan <[email protected]>
AuthorDate: Sat Oct 3 03:10:36 2026 +0000

    fix(arrow-string): sum view element lengths in usize when concatenating 
(#11318)
    
    ### Which issue does this PR close?
    
    - Closes #11317.
    
    ### Rationale for this change
    
    the two element lengths are u32 and were added as u32, so a pair that
    sums past u32::MAX wrapped before the size check could see it. the check
    passed on the wrapped number and the result came back with an empty
    value where the data belongs.
    
    ### What changes are included in this PR?
    
    the addition is done in usize. nothing else moves, the existing i32::MAX
    check now sees the real total and rejects it.
    
    ### Are these changes tested?
    
    yes, two 2 GiB elements concatenated. the test is ignored by default
    since it wants around 8 GiB, run it with cargo test --release -p
    arrow-string -- --ignored. without the fix it returns Ok with an empty
    element, with the fix it returns the overflow error.
    
    ### Are there any user-facing changes?
    
    concat of view elements that together pass u32::MAX returns an error now
    instead of wrong data.
---
 arrow-string/src/concat_elements.rs | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/arrow-string/src/concat_elements.rs 
b/arrow-string/src/concat_elements.rs
index 0a7e76f045..fd83b45d22 100644
--- a/arrow-string/src/concat_elements.rs
+++ b/arrow-string/src/concat_elements.rs
@@ -277,23 +277,23 @@ where
         let null_buffer = NullBuffer::union(left.nulls(), right.nulls());
 
         // Compute the required data buffer size, excluding any elements that 
are null
-        // or are small enough to be stored inline.
-        let data_size = match &null_buffer {
+        // or are small enough to be stored inline. Both lengths are `u32`, 
and a
+        // pair of them can sum past that, so the addition is done in `usize`.
+        let inline_max = MAX_INLINE_VIEW_LEN as usize;
+        let data_size: usize = match &null_buffer {
             None => left
                 .lengths()
                 .zip(right.lengths())
-                .map(|(l, r)| l + r)
-                .filter(|len| *len > MAX_INLINE_VIEW_LEN)
-                .map(|len| len as usize)
+                .map(|(l, r)| l as usize + r as usize)
+                .filter(|len| *len > inline_max)
                 .sum(),
             Some(nb) => left
                 .lengths()
                 .zip(right.lengths())
                 .zip(nb.iter())
                 .filter(|((_, _), not_null)| *not_null)
-                .map(|((l, r), _)| l + r)
-                .filter(|len| *len > MAX_INLINE_VIEW_LEN)
-                .map(|len| len as usize)
+                .map(|((l, r), _)| l as usize + r as usize)
+                .filter(|len| *len > inline_max)
                 .sum(),
         };
 

Reply via email to