authorgravatar for matthew.h.borkowski@gmail.comMatthew Borkowski <matthew.h.borkowski@gmail.com> 2021-09-29 09:02:05-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2021-10-04 15:30:37-04:00
log66204b780699ca6f043d312b4c637c25d6d9f3eb
treed01838a189a4d49d2a03f1a599df1308f9fe952b
parent5125788e331c146ef5f5f33be775e3538353a0b6

deflate.zig: check for distances past beginning of output stream


1 files changed, 11 insertions(+), 2 deletions(-)

lib/std/compress/deflate.zig+11-2
......@@ -186,6 +186,7 @@ pub fn InflateStream(comptime ReaderType: type) type {
186186 wi: usize = 0, // Write index
187187 ri: usize = 0, // Read index
188188 el: usize = 0, // Number of readable elements
189 total_written: usize = 0,
189190
190191 fn readable(self: *WSelf) usize {
191192 return self.el;
......@@ -210,6 +211,7 @@ pub fn InflateStream(comptime ReaderType: type) type {
210211 self.buf[self.wi] = value;
211212 self.wi = (self.wi + 1) & (self.buf.len - 1);
212213 self.el += 1;
214 self.total_written += 1;
213215 }
214216
215217 // Fill dest[] with data from the window, starting from the read
......@@ -462,7 +464,7 @@ pub fn InflateStream(comptime ReaderType: type) type {
462464 const distance = DISTS[distance_symbol] +
463465 @intCast(u16, try self.readBits(DEXT[distance_symbol]));
464466
465 if (distance > self.window.buf.len)
467 if (distance > self.window.buf.len or distance > self.window.total_written)
466468 return error.InvalidDistance;
467469
468470 const written = self.window.copyFrom(distance, length);
......@@ -666,13 +668,20 @@ test "lengths overflow" {
666668}
667669
668670test "empty distance alphabet" {
669 // dynamic block with empty distance alphabet is valid if end of data symbol is used immediately
671 // dynamic block with empty distance alphabet is valid if only literals and end of data symbol are used
670672 // f dy hlit hdist hclen 16 17 18 0 8 7 9 6 10 5 11 4 12 3 13 2 14 1 15 (18) x128 (18) x128 (1) ( 0) (256)
671673 // 1 10 00000 00000 1111 000 000 010 010 000 000 000 000 000 000 000 000 000 000 000 000 000 001 000 (11) 1110101 (11) 1110101 (0) (10) (0)
672674 const stream = [_]u8{ 0b00000101, 0b11100000, 0b00000001, 0b00001001, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00010000, 0b01011100, 0b10111111, 0b00101110 };
673675 try testInflate(stream[0..]);
674676}
675677
678test "distance past beginning of output stream" {
679 // f fx ('A') ('B') ('C') <len=4, dist=4> (end)
680 // 1 01 (01110001) (01110010) (01110011) (0000010) (00011) (0000000)
681 const stream = [_]u8{ 0b01110011, 0b01110100, 0b01110010, 0b00000110, 0b01100001, 0b00000000 };
682 try std.testing.expectError(error.InvalidDistance, testInflate(stream[0..]));
683}
684
676685test "inflateStream fuzzing" {
677686 // see https://github.com/ziglang/zig/issues/9842
678687 try std.testing.expectError(error.EndOfStream, testInflate("\x950000"));