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