| ... | ... | @@ -391,15 +391,21 @@ pub const DecodeState = struct { |
| 391 | 391 | try self.literal_stream_reader.init(bytes); |
| 392 | 392 | } |
| 393 | 393 | |
| 394 | fn isLiteralStreamEmpty(self: *DecodeState) bool { |
| 395 | switch (self.literal_streams) { |
| 396 | .one => return self.literal_stream_reader.isEmpty(), |
| 397 | .four => return self.literal_stream_index == 3 and self.literal_stream_reader.isEmpty(), |
| 398 | } |
| 399 | } |
| 400 | |
| 394 | 401 | const LiteralBitsError = error{ |
| 395 | 402 | BitStreamHasNoStartBit, |
| 396 | 403 | UnexpectedEndOfLiteralStream, |
| 397 | 404 | }; |
| 398 | 405 | fn readLiteralsBits( |
| 399 | 406 | self: *DecodeState, |
| 400 | | comptime T: type, |
| 401 | 407 | bit_count_to_read: usize, |
| 402 | | ) LiteralBitsError!T { |
| 408 | ) LiteralBitsError!u16 { |
| 403 | 409 | return self.literal_stream_reader.readBitsNoEof(u16, bit_count_to_read) catch bits: { |
| 404 | 410 | if (self.literal_streams == .four and self.literal_stream_index < 3) { |
| 405 | 411 | try self.nextLiteralMultiStream(); |
| ... | ... | @@ -461,7 +467,7 @@ pub const DecodeState = struct { |
| 461 | 467 | while (i < len) : (i += 1) { |
| 462 | 468 | var prefix: u16 = 0; |
| 463 | 469 | while (true) { |
| 464 | | const new_bits = self.readLiteralsBits(u16, bit_count_to_read) catch |err| { |
| 470 | const new_bits = self.readLiteralsBits(bit_count_to_read) catch |err| { |
| 465 | 471 | return err; |
| 466 | 472 | }; |
| 467 | 473 | prefix <<= bit_count_to_read; |
| ... | ... | @@ -533,7 +539,7 @@ pub const DecodeState = struct { |
| 533 | 539 | while (i < len) : (i += 1) { |
| 534 | 540 | var prefix: u16 = 0; |
| 535 | 541 | while (true) { |
| 536 | | const new_bits = try self.readLiteralsBits(u16, bit_count_to_read); |
| 542 | const new_bits = try self.readLiteralsBits(bit_count_to_read); |
| 537 | 543 | prefix <<= bit_count_to_read; |
| 538 | 544 | prefix |= new_bits; |
| 539 | 545 | bits_read += bit_count_to_read; |
| ... | ... | @@ -659,13 +665,10 @@ pub fn decodeBlock( |
| 659 | 665 | sequence_size_limit -= decompressed_size; |
| 660 | 666 | } |
| 661 | 667 | |
| 662 | | if (bit_stream.bit_reader.bit_count != 0) { |
| 668 | if (!bit_stream.isEmpty()) { |
| 663 | 669 | return error.MalformedCompressedBlock; |
| 664 | 670 | } |
| 665 | | |
| 666 | | bytes_read += bit_stream_bytes.len; |
| 667 | 671 | } |
| 668 | | if (bytes_read != block_size) return error.MalformedCompressedBlock; |
| 669 | 672 | |
| 670 | 673 | if (decode_state.literal_written_count < literals.header.regenerated_size) { |
| 671 | 674 | const len = literals.header.regenerated_size - decode_state.literal_written_count; |
| ... | ... | @@ -675,7 +678,9 @@ pub fn decodeBlock( |
| 675 | 678 | bytes_written += len; |
| 676 | 679 | } |
| 677 | 680 | |
| 678 | | consumed_count.* += bytes_read; |
| 681 | if (!decode_state.isLiteralStreamEmpty()) return error.MalformedCompressedBlock; |
| 682 | |
| 683 | consumed_count.* += block_size; |
| 679 | 684 | return bytes_written; |
| 680 | 685 | }, |
| 681 | 686 | .reserved => return error.ReservedBlock, |
| ... | ... | @@ -749,13 +754,10 @@ pub fn decodeBlockRingBuffer( |
| 749 | 754 | sequence_size_limit -= decompressed_size; |
| 750 | 755 | } |
| 751 | 756 | |
| 752 | | if (bit_stream.bit_reader.bit_count != 0) { |
| 757 | if (!bit_stream.isEmpty()) { |
| 753 | 758 | return error.MalformedCompressedBlock; |
| 754 | 759 | } |
| 755 | | |
| 756 | | bytes_read += bit_stream_bytes.len; |
| 757 | 760 | } |
| 758 | | if (bytes_read != block_size) return error.MalformedCompressedBlock; |
| 759 | 761 | |
| 760 | 762 | if (decode_state.literal_written_count < literals.header.regenerated_size) { |
| 761 | 763 | const len = literals.header.regenerated_size - decode_state.literal_written_count; |
| ... | ... | @@ -764,7 +766,9 @@ pub fn decodeBlockRingBuffer( |
| 764 | 766 | bytes_written += len; |
| 765 | 767 | } |
| 766 | 768 | |
| 767 | | consumed_count.* += bytes_read; |
| 769 | if (!decode_state.isLiteralStreamEmpty()) return error.MalformedCompressedBlock; |
| 770 | |
| 771 | consumed_count.* += block_size; |
| 768 | 772 | if (bytes_written > block_size_max) return error.BlockSizeOverMaximum; |
| 769 | 773 | return bytes_written; |
| 770 | 774 | }, |
| ... | ... | @@ -837,7 +841,7 @@ pub fn decodeBlockReader( |
| 837 | 841 | sequence_size_limit -= decompressed_size; |
| 838 | 842 | bytes_written += decompressed_size; |
| 839 | 843 | } |
| 840 | | if (bit_stream.bit_reader.bit_count != 0) { |
| 844 | if (!bit_stream.isEmpty()) { |
| 841 | 845 | return error.MalformedCompressedBlock; |
| 842 | 846 | } |
| 843 | 847 | } |
| ... | ... | @@ -849,6 +853,8 @@ pub fn decodeBlockReader( |
| 849 | 853 | bytes_written += len; |
| 850 | 854 | } |
| 851 | 855 | |
| 856 | if (!decode_state.isLiteralStreamEmpty()) return error.MalformedCompressedBlock; |
| 857 | |
| 852 | 858 | if (bytes_written > block_size_max) return error.BlockSizeOverMaximum; |
| 853 | 859 | if (block_reader_limited.bytes_left != 0) return error.MalformedCompressedBlock; |
| 854 | 860 | decode_state.literal_written_count = 0; |