authorgravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-02-13 17:19:33+11:00
committergravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-02-20 09:09:06+11:00
log12aa478db08c5652d27228183bb898f65db7a2ae
treeac349f366919bcb8d6157787ede3e10f423dfba8
parenta53cf299a6a22422d734d54b6abed4ff8b6473c5

std.compress.zstandard: also check block size when sequence count is 0


2 files changed, 62 insertions(+), 51 deletions(-)

lib/std/compress/zstandard/decode/block.zig+60-50
......@@ -654,29 +654,32 @@ pub fn decodeBlock(
654654 bytes_read += fbs.pos;
655655
656656 var bytes_written: usize = 0;
657 if (sequences_header.sequence_count > 0) {
657 {
658658 const bit_stream_bytes = src[bytes_read..block_size];
659659 var bit_stream: readers.ReverseBitReader = undefined;
660660 bit_stream.init(bit_stream_bytes) catch return error.MalformedCompressedBlock;
661661
662 decode_state.readInitialFseState(&bit_stream) catch return error.MalformedCompressedBlock;
663
664 var sequence_size_limit = block_size_max;
665 var i: usize = 0;
666 while (i < sequences_header.sequence_count) : (i += 1) {
667 const write_pos = written_count + bytes_written;
668 const decompressed_size = decode_state.decodeSequenceSlice(
669 dest,
670 write_pos,
671 &bit_stream,
672 sequence_size_limit,
673 i == sequences_header.sequence_count - 1,
674 ) catch |err| switch (err) {
675 error.DestTooSmall => return error.DestTooSmall,
676 else => return error.MalformedCompressedBlock,
677 };
678 bytes_written += decompressed_size;
679 sequence_size_limit -= decompressed_size;
662 if (sequences_header.sequence_count > 0) {
663 decode_state.readInitialFseState(&bit_stream) catch
664 return error.MalformedCompressedBlock;
665
666 var sequence_size_limit = block_size_max;
667 var i: usize = 0;
668 while (i < sequences_header.sequence_count) : (i += 1) {
669 const write_pos = written_count + bytes_written;
670 const decompressed_size = decode_state.decodeSequenceSlice(
671 dest,
672 write_pos,
673 &bit_stream,
674 sequence_size_limit,
675 i == sequences_header.sequence_count - 1,
676 ) catch |err| switch (err) {
677 error.DestTooSmall => return error.DestTooSmall,
678 else => return error.MalformedCompressedBlock,
679 };
680 bytes_written += decompressed_size;
681 sequence_size_limit -= decompressed_size;
682 }
680683 }
681684
682685 if (!bit_stream.isEmpty()) {
......@@ -755,24 +758,27 @@ pub fn decodeBlockRingBuffer(
755758 bytes_read += fbs.pos;
756759
757760 var bytes_written: usize = 0;
758 if (sequences_header.sequence_count > 0) {
761 {
759762 const bit_stream_bytes = src[bytes_read..block_size];
760763 var bit_stream: readers.ReverseBitReader = undefined;
761764 bit_stream.init(bit_stream_bytes) catch return error.MalformedCompressedBlock;
762765
763 decode_state.readInitialFseState(&bit_stream) catch return error.MalformedCompressedBlock;
764
765 var sequence_size_limit = block_size_max;
766 var i: usize = 0;
767 while (i < sequences_header.sequence_count) : (i += 1) {
768 const decompressed_size = decode_state.decodeSequenceRingBuffer(
769 dest,
770 &bit_stream,
771 sequence_size_limit,
772 i == sequences_header.sequence_count - 1,
773 ) catch return error.MalformedCompressedBlock;
774 bytes_written += decompressed_size;
775 sequence_size_limit -= decompressed_size;
766 if (sequences_header.sequence_count > 0) {
767 decode_state.readInitialFseState(&bit_stream) catch
768 return error.MalformedCompressedBlock;
769
770 var sequence_size_limit = block_size_max;
771 var i: usize = 0;
772 while (i < sequences_header.sequence_count) : (i += 1) {
773 const decompressed_size = decode_state.decodeSequenceRingBuffer(
774 dest,
775 &bit_stream,
776 sequence_size_limit,
777 i == sequences_header.sequence_count - 1,
778 ) catch return error.MalformedCompressedBlock;
779 bytes_written += decompressed_size;
780 sequence_size_limit -= decompressed_size;
781 }
776782 }
777783
778784 if (!bit_stream.isEmpty()) {
......@@ -847,28 +853,32 @@ pub fn decodeBlockReader(
847853 try decode_state.prepare(block_reader, literals, sequences_header);
848854
849855 var bytes_written: usize = 0;
850 if (sequences_header.sequence_count > 0) {
851 if (sequence_buffer.len < block_reader_limited.bytes_left)
852 return error.SequenceBufferTooSmall;
853
856 {
854857 const size = try block_reader.readAll(sequence_buffer);
855858 var bit_stream: readers.ReverseBitReader = undefined;
856859 try bit_stream.init(sequence_buffer[0..size]);
857860
858 decode_state.readInitialFseState(&bit_stream) catch return error.MalformedCompressedBlock;
859
860 var sequence_size_limit = block_size_max;
861 var i: usize = 0;
862 while (i < sequences_header.sequence_count) : (i += 1) {
863 const decompressed_size = decode_state.decodeSequenceRingBuffer(
864 dest,
865 &bit_stream,
866 sequence_size_limit,
867 i == sequences_header.sequence_count - 1,
868 ) catch return error.MalformedCompressedBlock;
869 sequence_size_limit -= decompressed_size;
870 bytes_written += decompressed_size;
861 if (sequences_header.sequence_count > 0) {
862 if (sequence_buffer.len < block_reader_limited.bytes_left)
863 return error.SequenceBufferTooSmall;
864
865 decode_state.readInitialFseState(&bit_stream) catch
866 return error.MalformedCompressedBlock;
867
868 var sequence_size_limit = block_size_max;
869 var i: usize = 0;
870 while (i < sequences_header.sequence_count) : (i += 1) {
871 const decompressed_size = decode_state.decodeSequenceRingBuffer(
872 dest,
873 &bit_stream,
874 sequence_size_limit,
875 i == sequences_header.sequence_count - 1,
876 ) catch return error.MalformedCompressedBlock;
877 sequence_size_limit -= decompressed_size;
878 bytes_written += decompressed_size;
879 }
871880 }
881
872882 if (!bit_stream.isEmpty()) {
873883 return error.MalformedCompressedBlock;
874884 }
lib/std/compress/zstandard/readers.zig+2-1
......@@ -36,8 +36,9 @@ pub const ReverseBitReader = struct {
3636 pub fn init(self: *ReverseBitReader, bytes: []const u8) error{BitStreamHasNoStartBit}!void {
3737 self.byte_reader = ReversedByteReader.init(bytes);
3838 self.bit_reader = std.io.bitReader(.Big, self.byte_reader.reader());
39 if (bytes.len == 0) return;
3940 var i: usize = 0;
40 while (i < 8 and 0 == self.readBitsNoEof(u1, 1) catch return error.BitStreamHasNoStartBit) : (i += 1) {}
41 while (i < 8 and 0 == self.readBitsNoEof(u1, 1) catch unreachable) : (i += 1) {}
4142 if (i == 8) return error.BitStreamHasNoStartBit;
4243 }
4344