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 {...@@ -186,6 +186,7 @@ pub fn InflateStream(comptime ReaderType: type) type {
186 wi: usize = 0, // Write index186 wi: usize = 0, // Write index
187 ri: usize = 0, // Read index187 ri: usize = 0, // Read index
188 el: usize = 0, // Number of readable elements188 el: usize = 0, // Number of readable elements
189 total_written: usize = 0,
189190
190 fn readable(self: *WSelf) usize {191 fn readable(self: *WSelf) usize {
191 return self.el;192 return self.el;
...@@ -210,6 +211,7 @@ pub fn InflateStream(comptime ReaderType: type) type {...@@ -210,6 +211,7 @@ pub fn InflateStream(comptime ReaderType: type) type {
210 self.buf[self.wi] = value;211 self.buf[self.wi] = value;
211 self.wi = (self.wi + 1) & (self.buf.len - 1);212 self.wi = (self.wi + 1) & (self.buf.len - 1);
212 self.el += 1;213 self.el += 1;
214 self.total_written += 1;
213 }215 }
214216
215 // Fill dest[] with data from the window, starting from the read217 // Fill dest[] with data from the window, starting from the read
...@@ -462,7 +464,7 @@ pub fn InflateStream(comptime ReaderType: type) type {...@@ -462,7 +464,7 @@ pub fn InflateStream(comptime ReaderType: type) type {
462 const distance = DISTS[distance_symbol] +464 const distance = DISTS[distance_symbol] +
463 @intCast(u16, try self.readBits(DEXT[distance_symbol]));465 @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)
466 return error.InvalidDistance;468 return error.InvalidDistance;
467469
468 const written = self.window.copyFrom(distance, length);470 const written = self.window.copyFrom(distance, length);
...@@ -666,13 +668,20 @@ test "lengths overflow" {...@@ -666,13 +668,20 @@ test "lengths overflow" {
666}668}
667669
668test "empty distance alphabet" {670test "empty distance alphabet" {
669 // dynamic block with empty distance alphabet is valid if end of data symbol is used immediately671 // dynamic block with empty distance alphabet is valid if only literals and end of data symbol are used
670 // 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)672 // 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)
671 // 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)673 // 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)
672 const stream = [_]u8{ 0b00000101, 0b11100000, 0b00000001, 0b00001001, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00010000, 0b01011100, 0b10111111, 0b00101110 };674 const stream = [_]u8{ 0b00000101, 0b11100000, 0b00000001, 0b00001001, 0b00000000, 0b00000000, 0b00000000, 0b00000000, 0b00010000, 0b01011100, 0b10111111, 0b00101110 };
673 try testInflate(stream[0..]);675 try testInflate(stream[0..]);
674}676}
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
676test "inflateStream fuzzing" {685test "inflateStream fuzzing" {
677 // see https://github.com/ziglang/zig/issues/9842686 // see https://github.com/ziglang/zig/issues/9842
678 try std.testing.expectError(error.EndOfStream, testInflate("\x950000"));687 try std.testing.expectError(error.EndOfStream, testInflate("\x950000"));