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