| ... | @@ -391,15 +391,21 @@ pub const DecodeState = struct { | ... | @@ -391,15 +391,21 @@ pub const DecodeState = struct { |
| 391 | try self.literal_stream_reader.init(bytes); | 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 | const LiteralBitsError = error{ | 401 | const LiteralBitsError = error{ |
| 395 | BitStreamHasNoStartBit, | 402 | BitStreamHasNoStartBit, |
| 396 | UnexpectedEndOfLiteralStream, | 403 | UnexpectedEndOfLiteralStream, |
| 397 | }; | 404 | }; |
| 398 | fn readLiteralsBits( | 405 | fn readLiteralsBits( |
| 399 | self: *DecodeState, | 406 | self: *DecodeState, |
| 400 | comptime T: type, | | |
| 401 | bit_count_to_read: usize, | 407 | bit_count_to_read: usize, |
| 402 | ) LiteralBitsError!T { | 408 | ) LiteralBitsError!u16 { |
| 403 | return self.literal_stream_reader.readBitsNoEof(u16, bit_count_to_read) catch bits: { | 409 | return self.literal_stream_reader.readBitsNoEof(u16, bit_count_to_read) catch bits: { |
| 404 | if (self.literal_streams == .four and self.literal_stream_index < 3) { | 410 | if (self.literal_streams == .four and self.literal_stream_index < 3) { |
| 405 | try self.nextLiteralMultiStream(); | 411 | try self.nextLiteralMultiStream(); |
| ... | @@ -461,7 +467,7 @@ pub const DecodeState = struct { | ... | @@ -461,7 +467,7 @@ pub const DecodeState = struct { |
| 461 | while (i < len) : (i += 1) { | 467 | while (i < len) : (i += 1) { |
| 462 | var prefix: u16 = 0; | 468 | var prefix: u16 = 0; |
| 463 | while (true) { | 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 | return err; | 471 | return err; |
| 466 | }; | 472 | }; |
| 467 | prefix <<= bit_count_to_read; | 473 | prefix <<= bit_count_to_read; |
| ... | @@ -533,7 +539,7 @@ pub const DecodeState = struct { | ... | @@ -533,7 +539,7 @@ pub const DecodeState = struct { |
| 533 | while (i < len) : (i += 1) { | 539 | while (i < len) : (i += 1) { |
| 534 | var prefix: u16 = 0; | 540 | var prefix: u16 = 0; |
| 535 | while (true) { | 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 | prefix <<= bit_count_to_read; | 543 | prefix <<= bit_count_to_read; |
| 538 | prefix |= new_bits; | 544 | prefix |= new_bits; |
| 539 | bits_read += bit_count_to_read; | 545 | bits_read += bit_count_to_read; |
| ... | @@ -659,13 +665,10 @@ pub fn decodeBlock( | ... | @@ -659,13 +665,10 @@ pub fn decodeBlock( |
| 659 | sequence_size_limit -= decompressed_size; | 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 | return error.MalformedCompressedBlock; | 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 | if (decode_state.literal_written_count < literals.header.regenerated_size) { | 673 | if (decode_state.literal_written_count < literals.header.regenerated_size) { |
| 671 | const len = literals.header.regenerated_size - decode_state.literal_written_count; | 674 | const len = literals.header.regenerated_size - decode_state.literal_written_count; |
| ... | @@ -675,7 +678,9 @@ pub fn decodeBlock( | ... | @@ -675,7 +678,9 @@ pub fn decodeBlock( |
| 675 | bytes_written += len; | 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 | return bytes_written; | 684 | return bytes_written; |
| 680 | }, | 685 | }, |
| 681 | .reserved => return error.ReservedBlock, | 686 | .reserved => return error.ReservedBlock, |
| ... | @@ -749,13 +754,10 @@ pub fn decodeBlockRingBuffer( | ... | @@ -749,13 +754,10 @@ pub fn decodeBlockRingBuffer( |
| 749 | sequence_size_limit -= decompressed_size; | 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 | return error.MalformedCompressedBlock; | 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 | if (decode_state.literal_written_count < literals.header.regenerated_size) { | 762 | if (decode_state.literal_written_count < literals.header.regenerated_size) { |
| 761 | const len = literals.header.regenerated_size - decode_state.literal_written_count; | 763 | const len = literals.header.regenerated_size - decode_state.literal_written_count; |
| ... | @@ -764,7 +766,9 @@ pub fn decodeBlockRingBuffer( | ... | @@ -764,7 +766,9 @@ pub fn decodeBlockRingBuffer( |
| 764 | bytes_written += len; | 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 | if (bytes_written > block_size_max) return error.BlockSizeOverMaximum; | 772 | if (bytes_written > block_size_max) return error.BlockSizeOverMaximum; |
| 769 | return bytes_written; | 773 | return bytes_written; |
| 770 | }, | 774 | }, |
| ... | @@ -837,7 +841,7 @@ pub fn decodeBlockReader( | ... | @@ -837,7 +841,7 @@ pub fn decodeBlockReader( |
| 837 | sequence_size_limit -= decompressed_size; | 841 | sequence_size_limit -= decompressed_size; |
| 838 | bytes_written += decompressed_size; | 842 | bytes_written += decompressed_size; |
| 839 | } | 843 | } |
| 840 | if (bit_stream.bit_reader.bit_count != 0) { | 844 | if (!bit_stream.isEmpty()) { |
| 841 | return error.MalformedCompressedBlock; | 845 | return error.MalformedCompressedBlock; |
| 842 | } | 846 | } |
| 843 | } | 847 | } |
| ... | @@ -849,6 +853,8 @@ pub fn decodeBlockReader( | ... | @@ -849,6 +853,8 @@ pub fn decodeBlockReader( |
| 849 | bytes_written += len; | 853 | bytes_written += len; |
| 850 | } | 854 | } |
| 851 | | 855 | |
| | 856 | if (!decode_state.isLiteralStreamEmpty()) return error.MalformedCompressedBlock; |
| | 857 | |
| 852 | if (bytes_written > block_size_max) return error.BlockSizeOverMaximum; | 858 | if (bytes_written > block_size_max) return error.BlockSizeOverMaximum; |
| 853 | if (block_reader_limited.bytes_left != 0) return error.MalformedCompressedBlock; | 859 | if (block_reader_limited.bytes_left != 0) return error.MalformedCompressedBlock; |
| 854 | decode_state.literal_written_count = 0; | 860 | decode_state.literal_written_count = 0; |