| ... | @@ -31,6 +31,7 @@ const BlockType = enum(u2) { | ... | @@ -31,6 +31,7 @@ const BlockType = enum(u2) { |
| 31 | stored = 0, | 31 | stored = 0, |
| 32 | fixed = 1, | 32 | fixed = 1, |
| 33 | dynamic = 2, | 33 | dynamic = 2, |
| | 34 | invalid = 3, |
| 34 | }; | 35 | }; |
| 35 | | 36 | |
| 36 | const State = union(enum) { | 37 | const State = union(enum) { |
| ... | @@ -49,6 +50,7 @@ pub const Error = Container.Error || error{ | ... | @@ -49,6 +50,7 @@ pub const Error = Container.Error || error{ |
| 49 | InvalidCode, | 50 | InvalidCode, |
| 50 | InvalidMatch, | 51 | InvalidMatch, |
| 51 | WrongStoredBlockNlen, | 52 | WrongStoredBlockNlen, |
| | 53 | InvalidBlockType, |
| 52 | InvalidDynamicBlockHeader, | 54 | InvalidDynamicBlockHeader, |
| 53 | ReadFailed, | 55 | ReadFailed, |
| 54 | OversubscribedHuffmanTree, | 56 | OversubscribedHuffmanTree, |
| ... | @@ -360,6 +362,7 @@ fn streamInner(d: *Decompress, w: *Writer, limit: std.Io.Limit) (Error || Reader | ... | @@ -360,6 +362,7 @@ fn streamInner(d: *Decompress, w: *Writer, limit: std.Io.Limit) (Error || Reader |
| 360 | | 362 | |
| 361 | continue :sw .dynamic_block; | 363 | continue :sw .dynamic_block; |
| 362 | }, | 364 | }, |
| | 365 | .invalid => return error.InvalidBlockType, |
| 363 | } | 366 | } |
| 364 | }, | 367 | }, |
| 365 | .stored_block => |remaining_len| { | 368 | .stored_block => |remaining_len| { |
| ... | @@ -1141,6 +1144,10 @@ test "puff09" { | ... | @@ -1141,6 +1144,10 @@ test "puff09" { |
| 1141 | try testDecompress(.raw, @embedFile("testdata/fuzz/puff09.input"), "P"); | 1144 | try testDecompress(.raw, @embedFile("testdata/fuzz/puff09.input"), "P"); |
| 1142 | } | 1145 | } |
| 1143 | | 1146 | |
| | 1147 | test "invalid block type" { |
| | 1148 | try testFailure(.raw, &[_]u8{0b110}, error.InvalidBlockType); |
| | 1149 | } |
| | 1150 | |
| 1144 | test "bug 18966" { | 1151 | test "bug 18966" { |
| 1145 | try testDecompress( | 1152 | try testDecompress( |
| 1146 | .gzip, | 1153 | .gzip, |