| 689 | |
| 690 | template <typename Handler> |
| 691 | auto RleBitPackedParser::PeekImpl(Handler&& handler) const |
| 692 | -> std::pair<rle_size_t, ControlFlow> { |
| 693 | ARROW_DCHECK(!exhausted()); |
| 694 | |
| 695 | constexpr auto kMaxSize = bit_util::kMaxLEB128ByteLenFor<uint32_t>; |
| 696 | uint32_t run_len_type = 0; |
| 697 | const auto header_bytes = |
| 698 | bit_util::ParseLeadingLEB128(data_, std::min(kMaxSize, data_size_), &run_len_type); |
| 699 | if (ARROW_PREDICT_FALSE(header_bytes == 0)) { |
| 700 | // Malformed LEB128 data |
| 701 | return {0, ControlFlow::Break}; |
| 702 | } |
| 703 | |
| 704 | const bool is_bit_packed = run_len_type & 1; |
| 705 | const uint32_t count = run_len_type >> 1; |
| 706 | if (is_bit_packed) { |
| 707 | // Bit-packed run |
| 708 | constexpr auto kMaxCount = internal::max_size_for_v<rle_size_t> / 8; |
| 709 | if (ARROW_PREDICT_FALSE(count == 0 || count > kMaxCount)) { |
| 710 | // Illegal number of encoded values |
| 711 | return {0, ControlFlow::Break}; |
| 712 | } |
| 713 | |
| 714 | ARROW_DCHECK_LT(static_cast<uint64_t>(count) * 8, |
| 715 | internal::max_size_for_v<rle_size_t>); |
| 716 | // Count Already divided by 8 for byte size calculations |
| 717 | auto bytes_read = header_bytes + static_cast<int64_t>(count) * value_bit_width_; |
| 718 | auto values_count = static_cast<rle_size_t>(count * 8); |
| 719 | if (ARROW_PREDICT_FALSE(bytes_read > data_size_)) { |
| 720 | // Bit-packed run would overflow data buffer, but we might still be able |
| 721 | // to return a truncated bit-packed such as generated by some non-compliant |
| 722 | // encoders. |
| 723 | // Example in GH-47981: column contains 25 5-bit values, has a single |
| 724 | // bit-packed run with count=4 (theoretically 32 values), but only 17 |
| 725 | // bytes of RLE-bit-packed data (including the one-byte header). |
| 726 | bytes_read = data_size_; |
| 727 | values_count = |
| 728 | static_cast<rle_size_t>((bytes_read - header_bytes) * 8 / value_bit_width_); |
| 729 | // Only allow errors where the bit-packed run is not padded to a multiple |
| 730 | // of 8 values. Larger truncation should not occur. |
| 731 | if (values_count <= static_cast<rle_size_t>((count - 1) * 8)) { |
| 732 | return {0, ControlFlow::Break}; |
| 733 | } |
| 734 | } |
| 735 | |
| 736 | auto control = handler.OnBitPackedRun( |
| 737 | BitPackedRun(data_ + header_bytes, values_count, value_bit_width_, |
| 738 | /* .max_read_bytes= */ data_size_ - header_bytes)); |
| 739 | |
| 740 | return {static_cast<rle_size_t>(bytes_read), control}; |
| 741 | } |
| 742 | |
| 743 | // RLE run |
| 744 | if (ARROW_PREDICT_FALSE(count == 0)) { |
| 745 | // Illegal number of encoded values |
| 746 | return {0, ControlFlow::Break}; |
| 747 | } |
| 748 |
nothing calls this directly
no test coverage detected