diff --git a/cpp/src/arrow/util/rle_encoding_internal.h b/cpp/src/arrow/util/rle_encoding_internal.h index 161a926f5dbb..7b4f21148089 100644 --- a/cpp/src/arrow/util/rle_encoding_internal.h +++ b/cpp/src/arrow/util/rle_encoding_internal.h @@ -371,15 +371,19 @@ class BitPackedRunDecoder { /// left. [[nodiscard]] rle_size_t GetBatch(value_type* out, rle_size_t batch_size, rle_size_t value_bit_width) { - const int bits_read = values_read_ * value_bit_width; - const int bytes_fully_read = bits_read / 8; + const int64_t bits_read = static_cast(values_read_) * value_bit_width; + const int64_t bytes_fully_read = bits_read / 8; + // The parser only creates runs whose full payload fits in max_read_bytes_ (see + // BitPackedRun), so the max_read_bytes difference below is in [0, max_read_bytes_] + // and fits an int. A negative (unbounded) max_read_bytes_ stays negative. + ARROW_DCHECK(max_read_bytes_ < 0 || bytes_fully_read <= max_read_bytes_); const uint8_t* unread_data = data_ + bytes_fully_read; const ::arrow::internal::UnpackOptions opts{ /* .batch_size= */ std::min(batch_size, remaining()), /* .bit_width= */ value_bit_width, - /* .bit_offset= */ bits_read % 8, - /* .max_read_bytes= */ max_read_bytes_ - bytes_fully_read, + /* .bit_offset= */ static_cast(bits_read % 8), + /* .max_read_bytes= */ static_cast(max_read_bytes_ - bytes_fully_read), }; if constexpr (std::is_same_v) {