authorgravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-02-02 18:01:03+11:00
committergravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-02-20 09:09:06+11:00
log6e3e72884bdc1a2f9f3ae372716b50803565e696
tree46cb12b36bbf3f64f93d874c49e8cd9adc5b2848
parenta180fcc93d3eff8add7b0344ddc77241dcf78f1e

std.compress.zstandard: fix crashes


1 files changed, 12 insertions(+), 6 deletions(-)

lib/std/compress/zstandard/decompress.zig+12-6
......@@ -695,11 +695,11 @@ pub fn decodeZStandardFrameAlloc(
695695 var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined;
696696 var offset_fse_data: [types.compressed_block.table_size_max.offset]Table.Fse = undefined;
697697
698 var block_header = decodeBlockHeader(src[consumed_count..][0..3]);
698 var block_header = try decodeBlockHeaderSlice(src[consumed_count..]);
699699 consumed_count += 3;
700700 var decode_state = DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data);
701701 while (true) : ({
702 block_header = decodeBlockHeader(src[consumed_count..][0..3]);
702 block_header = try decodeBlockHeaderSlice(src[consumed_count..]);
703703 consumed_count += 3;
704704 }) {
705705 if (block_header.block_size > frame_context.block_size_max) return error.BlockSizeOverMaximum;
......@@ -737,6 +737,7 @@ const DecodeBlockError = error{
737737 ReservedBlock,
738738 MalformedRleBlock,
739739 MalformedCompressedBlock,
740 EndOfStream,
740741};
741742
742743/// Convenience wrapper for decoding all blocks in a frame; see `decodeBlock()`.
......@@ -751,13 +752,13 @@ pub fn decodeFrameBlocks(
751752 var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined;
752753 var offset_fse_data: [types.compressed_block.table_size_max.offset]Table.Fse = undefined;
753754
754 var block_header = decodeBlockHeader(src[0..3]);
755 var block_header = try decodeBlockHeaderSlice(src);
755756 var bytes_read: usize = 3;
756757 defer consumed_count.* += bytes_read;
757758 var decode_state = DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data);
758759 var written_count: usize = 0;
759760 while (true) : ({
760 block_header = decodeBlockHeader(src[bytes_read..][0..3]);
761 block_header = try decodeBlockHeaderSlice(src[bytes_read..]);
761762 bytes_read += 3;
762763 }) {
763764 const written_size = try decodeBlock(
......@@ -847,6 +848,7 @@ pub fn decodeBlock(
847848
848849 bytes_read += bit_stream_bytes.len;
849850 }
851 if (bytes_read != block_size) return error.MalformedCompressedBlock;
850852
851853 if (decode_state.literal_written_count < literals.header.regenerated_size) {
852854 const len = literals.header.regenerated_size - decode_state.literal_written_count;
......@@ -855,7 +857,6 @@ pub fn decodeBlock(
855857 bytes_written += len;
856858 }
857859
858 assert(bytes_read == block_header.block_size);
859860 consumed_count.* += bytes_read;
860861 return bytes_written;
861862 },
......@@ -931,6 +932,7 @@ pub fn decodeBlockRingBuffer(
931932
932933 bytes_read += bit_stream_bytes.len;
933934 }
935 if (bytes_read != block_size) return error.MalformedCompressedBlock;
934936
935937 if (decode_state.literal_written_count < literals.header.regenerated_size) {
936938 const len = literals.header.regenerated_size - decode_state.literal_written_count;
......@@ -939,7 +941,6 @@ pub fn decodeBlockRingBuffer(
939941 bytes_written += len;
940942 }
941943
942 assert(bytes_read == block_header.block_size);
943944 consumed_count.* += bytes_read;
944945 if (bytes_written > block_size_max) return error.BlockSizeOverMaximum;
945946 return bytes_written;
......@@ -1101,6 +1102,11 @@ pub fn decodeBlockHeader(src: *const [3]u8) frame.ZStandard.Block.Header {
11011102 };
11021103}
11031104
1105pub 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
11041110/// Decode a `LiteralsSection` from `src`, incrementing `consumed_count` by the
11051111/// number of bytes the section uses.
11061112///