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(...@@ -654,29 +654,32 @@ pub fn decodeBlock(
654 bytes_read += fbs.pos;654 bytes_read += fbs.pos;
655655
656 var bytes_written: usize = 0;656 var bytes_written: usize = 0;
657 if (sequences_header.sequence_count > 0) {657 {
658 const bit_stream_bytes = src[bytes_read..block_size];658 const bit_stream_bytes = src[bytes_read..block_size];
659 var bit_stream: readers.ReverseBitReader = undefined;659 var bit_stream: readers.ReverseBitReader = undefined;
660 bit_stream.init(bit_stream_bytes) catch return error.MalformedCompressedBlock;660 bit_stream.init(bit_stream_bytes) catch return error.MalformedCompressedBlock;
661661
662 decode_state.readInitialFseState(&bit_stream) catch return error.MalformedCompressedBlock;662 if (sequences_header.sequence_count > 0) {
663663 decode_state.readInitialFseState(&bit_stream) catch
664 var sequence_size_limit = block_size_max;664 return error.MalformedCompressedBlock;
665 var i: usize = 0;665
666 while (i < sequences_header.sequence_count) : (i += 1) {666 var sequence_size_limit = block_size_max;
667 const write_pos = written_count + bytes_written;667 var i: usize = 0;
668 const decompressed_size = decode_state.decodeSequenceSlice(668 while (i < sequences_header.sequence_count) : (i += 1) {
669 dest,669 const write_pos = written_count + bytes_written;
670 write_pos,670 const decompressed_size = decode_state.decodeSequenceSlice(
671 &bit_stream,671 dest,
672 sequence_size_limit,672 write_pos,
673 i == sequences_header.sequence_count - 1,673 &bit_stream,
674 ) catch |err| switch (err) {674 sequence_size_limit,
675 error.DestTooSmall => return error.DestTooSmall,675 i == sequences_header.sequence_count - 1,
676 else => return error.MalformedCompressedBlock,676 ) catch |err| switch (err) {
677 };677 error.DestTooSmall => return error.DestTooSmall,
678 bytes_written += decompressed_size;678 else => return error.MalformedCompressedBlock,
679 sequence_size_limit -= decompressed_size;679 };
680 bytes_written += decompressed_size;
681 sequence_size_limit -= decompressed_size;
682 }
680 }683 }
681684
682 if (!bit_stream.isEmpty()) {685 if (!bit_stream.isEmpty()) {
...@@ -755,24 +758,27 @@ pub fn decodeBlockRingBuffer(...@@ -755,24 +758,27 @@ pub fn decodeBlockRingBuffer(
755 bytes_read += fbs.pos;758 bytes_read += fbs.pos;
756759
757 var bytes_written: usize = 0;760 var bytes_written: usize = 0;
758 if (sequences_header.sequence_count > 0) {761 {
759 const bit_stream_bytes = src[bytes_read..block_size];762 const bit_stream_bytes = src[bytes_read..block_size];
760 var bit_stream: readers.ReverseBitReader = undefined;763 var bit_stream: readers.ReverseBitReader = undefined;
761 bit_stream.init(bit_stream_bytes) catch return error.MalformedCompressedBlock;764 bit_stream.init(bit_stream_bytes) catch return error.MalformedCompressedBlock;
762765
763 decode_state.readInitialFseState(&bit_stream) catch return error.MalformedCompressedBlock;766 if (sequences_header.sequence_count > 0) {
764767 decode_state.readInitialFseState(&bit_stream) catch
765 var sequence_size_limit = block_size_max;768 return error.MalformedCompressedBlock;
766 var i: usize = 0;769
767 while (i < sequences_header.sequence_count) : (i += 1) {770 var sequence_size_limit = block_size_max;
768 const decompressed_size = decode_state.decodeSequenceRingBuffer(771 var i: usize = 0;
769 dest,772 while (i < sequences_header.sequence_count) : (i += 1) {
770 &bit_stream,773 const decompressed_size = decode_state.decodeSequenceRingBuffer(
771 sequence_size_limit,774 dest,
772 i == sequences_header.sequence_count - 1,775 &bit_stream,
773 ) catch return error.MalformedCompressedBlock;776 sequence_size_limit,
774 bytes_written += decompressed_size;777 i == sequences_header.sequence_count - 1,
775 sequence_size_limit -= decompressed_size;778 ) catch return error.MalformedCompressedBlock;
779 bytes_written += decompressed_size;
780 sequence_size_limit -= decompressed_size;
781 }
776 }782 }
777783
778 if (!bit_stream.isEmpty()) {784 if (!bit_stream.isEmpty()) {
...@@ -847,28 +853,32 @@ pub fn decodeBlockReader(...@@ -847,28 +853,32 @@ pub fn decodeBlockReader(
847 try decode_state.prepare(block_reader, literals, sequences_header);853 try decode_state.prepare(block_reader, literals, sequences_header);
848854
849 var bytes_written: usize = 0;855 var bytes_written: usize = 0;
850 if (sequences_header.sequence_count > 0) {856 {
851 if (sequence_buffer.len < block_reader_limited.bytes_left)
852 return error.SequenceBufferTooSmall;
853
854 const size = try block_reader.readAll(sequence_buffer);857 const size = try block_reader.readAll(sequence_buffer);
855 var bit_stream: readers.ReverseBitReader = undefined;858 var bit_stream: readers.ReverseBitReader = undefined;
856 try bit_stream.init(sequence_buffer[0..size]);859 try bit_stream.init(sequence_buffer[0..size]);
857860
858 decode_state.readInitialFseState(&bit_stream) catch return error.MalformedCompressedBlock;861 if (sequences_header.sequence_count > 0) {
859862 if (sequence_buffer.len < block_reader_limited.bytes_left)
860 var sequence_size_limit = block_size_max;863 return error.SequenceBufferTooSmall;
861 var i: usize = 0;864
862 while (i < sequences_header.sequence_count) : (i += 1) {865 decode_state.readInitialFseState(&bit_stream) catch
863 const decompressed_size = decode_state.decodeSequenceRingBuffer(866 return error.MalformedCompressedBlock;
864 dest,867
865 &bit_stream,868 var sequence_size_limit = block_size_max;
866 sequence_size_limit,869 var i: usize = 0;
867 i == sequences_header.sequence_count - 1,870 while (i < sequences_header.sequence_count) : (i += 1) {
868 ) catch return error.MalformedCompressedBlock;871 const decompressed_size = decode_state.decodeSequenceRingBuffer(
869 sequence_size_limit -= decompressed_size;872 dest,
870 bytes_written += decompressed_size;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 }
871 }880 }
881
872 if (!bit_stream.isEmpty()) {882 if (!bit_stream.isEmpty()) {
873 return error.MalformedCompressedBlock;883 return error.MalformedCompressedBlock;
874 }884 }
lib/std/compress/zstandard/readers.zig+2-1
...@@ -36,8 +36,9 @@ pub const ReverseBitReader = struct {...@@ -36,8 +36,9 @@ pub const ReverseBitReader = struct {
36 pub fn init(self: *ReverseBitReader, bytes: []const u8) error{BitStreamHasNoStartBit}!void {36 pub fn init(self: *ReverseBitReader, bytes: []const u8) error{BitStreamHasNoStartBit}!void {
37 self.byte_reader = ReversedByteReader.init(bytes);37 self.byte_reader = ReversedByteReader.init(bytes);
38 self.bit_reader = std.io.bitReader(.Big, self.byte_reader.reader());38 self.bit_reader = std.io.bitReader(.Big, self.byte_reader.reader());
39 if (bytes.len == 0) return;
39 var i: usize = 0;40 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) {}
41 if (i == 8) return error.BitStreamHasNoStartBit;42 if (i == 8) return error.BitStreamHasNoStartBit;
42 }43 }
4344