Describe the bug, including details regarding any error messages, version, and platform.
Problem
BitPackedRunDecoder::GetBatch in cpp/src/arrow/util/rle_encoding_internal.h computes the read position as values_read_ * value_bit_width in 32-bit int. This decoder handles untrusted parquet RLE/bit-packed data (dictionary indices and rep/def levels), and a single bit-packed run may legitimately hold close to 2^31 values.
Cause
Once roughly 256 MiB of a large run have been decoded, the product passes INT32_MAX and wraps negative. bytes_fully_read then goes negative and unread_data ends up before the buffer, giving an out-of-bounds read in unpack. All of the inputs involved are within parquet spec bounds, so there is nothing to reject here; the intermediate just needs a wider type.
Fix
BitPackedRun::raw_data_size already widens to int64_t before the same multiply, so the offset computation in GetBatch should do the same. PR: #50089.
Found on current main, platform independent.
Component(s)
C++, Parquet
Describe the bug, including details regarding any error messages, version, and platform.
Problem
BitPackedRunDecoder::GetBatchincpp/src/arrow/util/rle_encoding_internal.hcomputes the read position asvalues_read_ * value_bit_widthin 32-bitint. This decoder handles untrusted parquet RLE/bit-packed data (dictionary indices and rep/def levels), and a single bit-packed run may legitimately hold close to 2^31 values.Cause
Once roughly 256 MiB of a large run have been decoded, the product passes INT32_MAX and wraps negative.
bytes_fully_readthen goes negative andunread_dataends up before the buffer, giving an out-of-bounds read inunpack. All of the inputs involved are within parquet spec bounds, so there is nothing to reject here; the intermediate just needs a wider type.Fix
BitPackedRun::raw_data_sizealready widens toint64_tbefore the same multiply, so the offset computation inGetBatchshould do the same. PR: #50089.Found on current main, platform independent.
Component(s)
C++, Parquet