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

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


The following commit(s) were added to refs/heads/59_maintenance by this push:
     new 918ed327c9 [59_maintenance] fix: Parquet `ByteArrayDecoderPlain::read` 
can silently fail to read the correct number of values (#11440)
918ed327c9 is described below

commit 918ed327c998f119eeb6f221065e7970506aa70c
Author: Jeffrey Vo <[email protected]>
AuthorDate: Fri Oct 9 02:50:50 2026 +0900

    [59_maintenance] fix: Parquet `ByteArrayDecoderPlain::read` can silently 
fail to read the correct number of values (#11440)
    
    - Backport #11222
    - For inclusion in https://github.com/apache/arrow-rs/issues/11352
    
    Cherry-pick of
    
https://github.com/apache/arrow-rs/commit/fa337f843a8e8e666790b6b5833d69887aa7d2ce
    
    Co-authored-by: Ed Seidl <[email protected]>
---
 parquet/src/arrow/array_reader/byte_array.rs | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/parquet/src/arrow/array_reader/byte_array.rs 
b/parquet/src/arrow/array_reader/byte_array.rs
index 4fc32dd803..514462b558 100644
--- a/parquet/src/arrow/array_reader/byte_array.rs
+++ b/parquet/src/arrow/array_reader/byte_array.rs
@@ -414,12 +414,12 @@ impl ByteArrayDecoderPlain {
             self.offset = end_offset;
             read += 1;
         }
-        self.max_remaining_values -= to_read;
+        self.max_remaining_values -= read;
 
         if self.validate_utf8 {
             output.check_valid_utf8(initial_values_length)?;
         }
-        Ok(to_read)
+        Ok(read)
     }
 
     pub fn skip(&mut self, to_skip: usize) -> Result<usize> {
@@ -753,4 +753,18 @@ mod tests {
             assert_eq!(decoder.skip_values(1024).unwrap(), 0);
         }
     }
+
+    #[test]
+    fn test_plain_decoder_reports_values_actually_read() {
+        // The page claims to contain two values, but its buffer contains only
+        // one complete PLAIN-encoded BYTE_ARRAY value.
+        let buffer = Bytes::from_static(&[3, 0, 0, 0, b'f', b'o', b'o']);
+        let mut decoder = ByteArrayDecoderPlain::new(buffer, 2, Some(2), 
false);
+        let mut output = OffsetBuffer::<i32>::with_capacity(2);
+
+        assert_eq!(decoder.read(&mut output, 2).unwrap(), 1);
+        assert_eq!(output.values.as_slice(), b"foo");
+        assert_eq!(output.offsets.as_slice(), &[0, 3]);
+        assert_eq!(decoder.max_remaining_values, 1);
+    }
 }

Reply via email to