| 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,7 +155,7 @@ pub const Lzma2Decoder = struct { |
| 155 | accum: *LzAccumBuffer, | 155 | accum: *LzAccumBuffer, |
| 156 | reset_dict: bool, | 156 | reset_dict: bool, |
| 157 | ) !void { | 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 | if (reset_dict) { | 160 | if (reset_dict) { |
| 161 | try accum.reset(writer); | 161 | try accum.reset(writer); |
lib/std/compress/xz.zig+1-1| ... | @@ -118,7 +118,7 @@ pub fn Decompress(comptime ReaderType: type) type { | ... | @@ -118,7 +118,7 @@ pub fn Decompress(comptime ReaderType: type) type { |
| 118 | var hasher = std.compress.hashedReader(self.in_reader, Crc32.init()); | 118 | var hasher = std.compress.hashedReader(self.in_reader, Crc32.init()); |
| 119 | const hashed_reader = hasher.reader(); | 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 | if (backward_size != index_size) | 122 | if (backward_size != index_size) |
| 123 | return error.CorruptInput; | 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,7 +97,7 @@ pub fn Decoder(comptime ReaderType: type) type { |
| 97 | var header_hasher = std.compress.hashedReader(block_reader, Crc32.init()); | 97 | var header_hasher = std.compress.hashedReader(block_reader, Crc32.init()); |
| 98 | const header_reader = header_hasher.reader(); | 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 | if (header_size == 0) | 101 | if (header_size == 0) |
| 102 | return error.EndOfStreamWithNoError; | 102 | return error.EndOfStreamWithNoError; |
| 103 | 103 |
lib/std/compress/xz/test.zig+20| ... | @@ -78,3 +78,23 @@ test "unsupported" { | ... | @@ -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 | } |