| author | |
| committer | |
| log | d57813e3e94e77f54e989fa0814216389cf04a2b |
| tree | 9cced097b3807e83656b62c1282513f1dada2acc |
| parent | baa877fd129c7c6eb3c87c3e219bb4dede67b0a0 |
4 files changed, 23 insertions(+), 3 deletions(-)
lib/std/compress/lzma/decode/lzma2.zig+1-1| ... | ... | @@ -155,7 +155,7 @@ pub const Lzma2Decoder = struct { |
| 155 | 155 | accum: *LzAccumBuffer, |
| 156 | 156 | reset_dict: bool, |
| 157 | 157 | ) !void { |
| 158 | const unpacked_size = try reader.readIntBig(u16) + 1; // TODO: overflow | |
| 158 | const unpacked_size = @as(u17, try reader.readIntBig(u16)) + 1; | |
| 159 | 159 | |
| 160 | 160 | if (reset_dict) { |
| 161 | 161 | try accum.reset(writer); |
lib/std/compress/xz.zig+1-1| ... | ... | @@ -118,7 +118,7 @@ pub fn Decompress(comptime ReaderType: type) type { |
| 118 | 118 | var hasher = std.compress.hashedReader(self.in_reader, Crc32.init()); |
| 119 | 119 | const hashed_reader = hasher.reader(); |
| 120 | 120 | |
| 121 | const backward_size = (try hashed_reader.readIntLittle(u32) + 1) * 4; | |
| 121 | const backward_size = (@as(u64, try hashed_reader.readIntLittle(u32)) + 1) * 4; | |
| 122 | 122 | if (backward_size != index_size) |
| 123 | 123 | return error.CorruptInput; |
| 124 | 124 |
lib/std/compress/xz/block.zig+1-1| ... | ... | @@ -97,7 +97,7 @@ pub fn Decoder(comptime ReaderType: type) type { |
| 97 | 97 | var header_hasher = std.compress.hashedReader(block_reader, Crc32.init()); |
| 98 | 98 | const header_reader = header_hasher.reader(); |
| 99 | 99 | |
| 100 | const header_size = try header_reader.readByte() * 4; | |
| 100 | const header_size = @as(u64, try header_reader.readByte()) * 4; | |
| 101 | 101 | if (header_size == 0) |
| 102 | 102 | return error.EndOfStreamWithNoError; |
| 103 | 103 |
lib/std/compress/xz/test.zig+20| ... | ... | @@ -78,3 +78,23 @@ test "unsupported" { |
| 78 | 78 | ); |
| 79 | 79 | } |
| 80 | 80 | } |
| 81 | ||
| 82 | fn testDontPanic(data: []const u8) !void { | |
| 83 | const buf = decompress(data) catch |err| switch (err) { | |
| 84 | error.OutOfMemory => |e| return e, | |
| 85 | else => return, | |
| 86 | }; | |
| 87 | defer testing.allocator.free(buf); | |
| 88 | } | |
| 89 | ||
| 90 | test "size fields: integer overflow avoidance" { | |
| 91 | // These cases were found via fuzz testing and each previously caused | |
| 92 | // an integer overflow when decoding. We just want to ensure they no longer | |
| 93 | // cause a panic | |
| 94 | const header_size_overflow = "\xfd7zXZ\x00\x00\x01i\"\xde6z"; | |
| 95 | try testDontPanic(header_size_overflow); | |
| 96 | const lzma2_chunk_size_overflow = "\xfd7zXZ\x00\x00\x01i\"\xde6\x02\x00!\x01\x08\x00\x00\x00\xd8\x0f#\x13\x01\xff\xff"; | |
| 97 | try testDontPanic(lzma2_chunk_size_overflow); | |
| 98 | const backward_size_overflow = "\xfd7zXZ\x00\x00\x01i\"\xde6\x00\x00\x00\x00\x1c\xdfD!\x90B\x99\r\x01\x00\x00\xff\xff\x10\x00\x00\x00\x01DD\xff\xff\xff\x01"; | |
| 99 | try testDontPanic(backward_size_overflow); | |
| 100 | } |