Skip to content

Commit 66204b7

Browse files
mattborkandrewrk
authored andcommitted
deflate.zig: check for distances past beginning of output stream
1 parent 5125788 commit 66204b7

File tree

1 file changed

+11
-2
lines changed

1 file changed

+11
-2
lines changed

lib/std/compress/deflate.zig

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -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

668670
test "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

678+
test "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+
676685
test "inflateStream fuzzing" {
677686
// see https://github.com/ziglang/zig/issues/9842
678687
try std.testing.expectError(error.EndOfStream, testInflate("\x950000"));

0 commit comments

Comments
 (0)