| ... | @@ -695,11 +695,11 @@ pub fn decodeZStandardFrameAlloc( | ... | @@ -695,11 +695,11 @@ pub fn decodeZStandardFrameAlloc( |
| 695 | var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined; | 695 | var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined; |
| 696 | var offset_fse_data: [types.compressed_block.table_size_max.offset]Table.Fse = undefined; | 696 | var offset_fse_data: [types.compressed_block.table_size_max.offset]Table.Fse = undefined; |
| 697 | | 697 | |
| 698 | var block_header = decodeBlockHeader(src[consumed_count..][0..3]); | 698 | var block_header = try decodeBlockHeaderSlice(src[consumed_count..]); |
| 699 | consumed_count += 3; | 699 | consumed_count += 3; |
| 700 | var decode_state = DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data); | 700 | var decode_state = DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data); |
| 701 | while (true) : ({ | 701 | while (true) : ({ |
| 702 | block_header = decodeBlockHeader(src[consumed_count..][0..3]); | 702 | block_header = try decodeBlockHeaderSlice(src[consumed_count..]); |
| 703 | consumed_count += 3; | 703 | consumed_count += 3; |
| 704 | }) { | 704 | }) { |
| 705 | if (block_header.block_size > frame_context.block_size_max) return error.BlockSizeOverMaximum; | 705 | if (block_header.block_size > frame_context.block_size_max) return error.BlockSizeOverMaximum; |
| ... | @@ -737,6 +737,7 @@ const DecodeBlockError = error{ | ... | @@ -737,6 +737,7 @@ const DecodeBlockError = error{ |
| 737 | ReservedBlock, | 737 | ReservedBlock, |
| 738 | MalformedRleBlock, | 738 | MalformedRleBlock, |
| 739 | MalformedCompressedBlock, | 739 | MalformedCompressedBlock, |
| | 740 | EndOfStream, |
| 740 | }; | 741 | }; |
| 741 | | 742 | |
| 742 | /// Convenience wrapper for decoding all blocks in a frame; see `decodeBlock()`. | 743 | /// Convenience wrapper for decoding all blocks in a frame; see `decodeBlock()`. |
| ... | @@ -751,13 +752,13 @@ pub fn decodeFrameBlocks( | ... | @@ -751,13 +752,13 @@ pub fn decodeFrameBlocks( |
| 751 | var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined; | 752 | var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined; |
| 752 | var offset_fse_data: [types.compressed_block.table_size_max.offset]Table.Fse = undefined; | 753 | var offset_fse_data: [types.compressed_block.table_size_max.offset]Table.Fse = undefined; |
| 753 | | 754 | |
| 754 | var block_header = decodeBlockHeader(src[0..3]); | 755 | var block_header = try decodeBlockHeaderSlice(src); |
| 755 | var bytes_read: usize = 3; | 756 | var bytes_read: usize = 3; |
| 756 | defer consumed_count.* += bytes_read; | 757 | defer consumed_count.* += bytes_read; |
| 757 | var decode_state = DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data); | 758 | var decode_state = DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data); |
| 758 | var written_count: usize = 0; | 759 | var written_count: usize = 0; |
| 759 | while (true) : ({ | 760 | while (true) : ({ |
| 760 | block_header = decodeBlockHeader(src[bytes_read..][0..3]); | 761 | block_header = try decodeBlockHeaderSlice(src[bytes_read..]); |
| 761 | bytes_read += 3; | 762 | bytes_read += 3; |
| 762 | }) { | 763 | }) { |
| 763 | const written_size = try decodeBlock( | 764 | const written_size = try decodeBlock( |
| ... | @@ -847,6 +848,7 @@ pub fn decodeBlock( | ... | @@ -847,6 +848,7 @@ pub fn decodeBlock( |
| 847 | | 848 | |
| 848 | bytes_read += bit_stream_bytes.len; | 849 | bytes_read += bit_stream_bytes.len; |
| 849 | } | 850 | } |
| | 851 | if (bytes_read != block_size) return error.MalformedCompressedBlock; |
| 850 | | 852 | |
| 851 | if (decode_state.literal_written_count < literals.header.regenerated_size) { | 853 | if (decode_state.literal_written_count < literals.header.regenerated_size) { |
| 852 | const len = literals.header.regenerated_size - decode_state.literal_written_count; | 854 | const len = literals.header.regenerated_size - decode_state.literal_written_count; |
| ... | @@ -855,7 +857,6 @@ pub fn decodeBlock( | ... | @@ -855,7 +857,6 @@ pub fn decodeBlock( |
| 855 | bytes_written += len; | 857 | bytes_written += len; |
| 856 | } | 858 | } |
| 857 | | 859 | |
| 858 | assert(bytes_read == block_header.block_size); | | |
| 859 | consumed_count.* += bytes_read; | 860 | consumed_count.* += bytes_read; |
| 860 | return bytes_written; | 861 | return bytes_written; |
| 861 | }, | 862 | }, |
| ... | @@ -931,6 +932,7 @@ pub fn decodeBlockRingBuffer( | ... | @@ -931,6 +932,7 @@ pub fn decodeBlockRingBuffer( |
| 931 | | 932 | |
| 932 | bytes_read += bit_stream_bytes.len; | 933 | bytes_read += bit_stream_bytes.len; |
| 933 | } | 934 | } |
| | 935 | if (bytes_read != block_size) return error.MalformedCompressedBlock; |
| 934 | | 936 | |
| 935 | if (decode_state.literal_written_count < literals.header.regenerated_size) { | 937 | if (decode_state.literal_written_count < literals.header.regenerated_size) { |
| 936 | const len = literals.header.regenerated_size - decode_state.literal_written_count; | 938 | const len = literals.header.regenerated_size - decode_state.literal_written_count; |
| ... | @@ -939,7 +941,6 @@ pub fn decodeBlockRingBuffer( | ... | @@ -939,7 +941,6 @@ pub fn decodeBlockRingBuffer( |
| 939 | bytes_written += len; | 941 | bytes_written += len; |
| 940 | } | 942 | } |
| 941 | | 943 | |
| 942 | assert(bytes_read == block_header.block_size); | | |
| 943 | consumed_count.* += bytes_read; | 944 | consumed_count.* += bytes_read; |
| 944 | if (bytes_written > block_size_max) return error.BlockSizeOverMaximum; | 945 | if (bytes_written > block_size_max) return error.BlockSizeOverMaximum; |
| 945 | return bytes_written; | 946 | return bytes_written; |
| ... | @@ -1101,6 +1102,11 @@ pub fn decodeBlockHeader(src: *const [3]u8) frame.ZStandard.Block.Header { | ... | @@ -1101,6 +1102,11 @@ pub fn decodeBlockHeader(src: *const [3]u8) frame.ZStandard.Block.Header { |
| 1101 | }; | 1102 | }; |
| 1102 | } | 1103 | } |
| 1103 | | 1104 | |
| | 1105 | pub fn decodeBlockHeaderSlice(src: []const u8) error{EndOfStream}!frame.ZStandard.Block.Header { |
| | 1106 | if (src.len < 3) return error.EndOfStream; |
| | 1107 | return decodeBlockHeader(src[0..3]); |
| | 1108 | } |
| | 1109 | |
| 1104 | /// Decode a `LiteralsSection` from `src`, incrementing `consumed_count` by the | 1110 | /// Decode a `LiteralsSection` from `src`, incrementing `consumed_count` by the |
| 1105 | /// number of bytes the section uses. | 1111 | /// number of bytes the section uses. |
| 1106 | /// | 1112 | /// |