authorgravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-04-29 10:13:10-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-04-29 17:48:08-04:00
log585479500e1941da25bcc4c55a4c3abc69fec031
tree63a70310145ba3eb42e88715cd8cc5dbbad61390
parent687ef42f988191b6da78bfafbda0d2fe888697cc

check for overflow when reading code lengths for a block with dynamic Huffman codes


1 files changed, 18 insertions(+), 0 deletions(-)

lib/std/compress/deflate.zig+18
...@@ -384,6 +384,8 @@ pub fn InflateStream(comptime ReaderType: type) type {...@@ -384,6 +384,8 @@ pub fn InflateStream(comptime ReaderType: type) type {
384 const last_length = lengths[i - 1];384 const last_length = lengths[i - 1];
385 const repeat = 3 + (try self.readBits(2));385 const repeat = 3 + (try self.readBits(2));
386 const last_index = i + repeat;386 const last_index = i + repeat;
387 if (last_index > lengths.len)
388 return error.InvalidLength;
387 while (i < last_index) : (i += 1) {389 while (i < last_index) : (i += 1) {
388 lengths[i] = last_length;390 lengths[i] = last_length;
389 }391 }
...@@ -655,3 +657,19 @@ pub fn InflateStream(comptime ReaderType: type) type {...@@ -655,3 +657,19 @@ pub fn InflateStream(comptime ReaderType: type) type {
655pub fn inflateStream(reader: anytype, window_slice: []u8) InflateStream(@TypeOf(reader)) {657pub fn inflateStream(reader: anytype, window_slice: []u8) InflateStream(@TypeOf(reader)) {
656 return InflateStream(@TypeOf(reader)).init(reader, window_slice);658 return InflateStream(@TypeOf(reader)).init(reader, window_slice);
657}659}
660
661test "lengths overflow" {
662 // malformed final dynamic block, tries to write 321 code lengths (MAXCODES is 316)
663 // f dy hlit hdist hclen 16 17 18 0 (18) x138 (18) x138 (18) x39 (16) x6
664 // 1 10 11101 11101 0000 010 010 010 010 (11) 1111111 (11) 1111111 (11) 0011100 (01) 11
665 const stream = [_]u8{
666 0b11101101, 0b00011101, 0b00100100, 0b11101001, 0b11111111, 0b11111111, 0b00111001, 0b00001110
667 };
668
669 const reader = std.io.fixedBufferStream(&stream).reader();
670 var window: [0x8000]u8 = undefined;
671 var inflate = inflateStream(reader, &window);
672
673 var buf: [1]u8 = undefined;
674 std.testing.expectError(error.InvalidLength, inflate.read(&buf));
675}