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);
+ }
}