authorgravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-12-04 14:32:25+02:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2022-12-04 14:32:25+02:00
loge361740669e95b198cfbbcb7a600edc3a0de273a
tree6ffb2e20a80a425853a2e691bfa71c5ebdde1711
parent8d17e90fcd3c54da5a271ad13eb114822c22d8da
parentb25fc18aa657fbc5b0fbc332123fdd0121d8ca1c
signaturebadge-question-mark Signed by PGP key 4AEE18F83AFDEB23

Merge pull request #13142 from mllken/gzip-safety

gzip: add missing header fields and bounds for header parsing

1 files changed, 25 insertions(+), 23 deletions(-)

lib/std/compress/gzip.zig+25-23
......@@ -15,6 +15,8 @@ const FEXTRA = 1 << 2;
1515const FNAME = 1 << 3;
1616const FCOMMENT = 1 << 4;
1717
18const max_string_len = 1024;
19
1820pub fn GzipStream(comptime ReaderType: type) type {
1921 return struct {
2022 const Self = @This();
......@@ -31,9 +33,11 @@ pub fn GzipStream(comptime ReaderType: type) type {
3133 read_amt: usize,
3234
3335 info: struct {
36 extra: ?[]const u8,
3437 filename: ?[]const u8,
3538 comment: ?[]const u8,
3639 modification_time: u32,
40 operating_system: u8,
3741 },
3842
3943 fn init(allocator: mem.Allocator, source: ReaderType) !Self {
......@@ -57,33 +61,27 @@ pub fn GzipStream(comptime ReaderType: type) type {
5761 // Operating system where the compression took place
5862 const OS = header[9];
5963 _ = XFL;
60 _ = OS;
6164
62 if (FLG & FEXTRA != 0) {
63 // Skip the extra data, we could read and expose it to the user
64 // if somebody needs it.
65 const extra = if (FLG & FEXTRA != 0) blk: {
6566 const len = try source.readIntLittle(u16);
66 try source.skipBytes(len, .{});
67 }
68
69 var filename: ?[]const u8 = null;
70 if (FLG & FNAME != 0) {
71 filename = try source.readUntilDelimiterAlloc(
72 allocator,
73 0,
74 std.math.maxInt(usize),
75 );
76 }
67 const tmp_buf = try allocator.alloc(u8, len);
68 errdefer allocator.free(tmp_buf);
69
70 try source.readNoEof(tmp_buf);
71 break :blk tmp_buf;
72 } else null;
73 errdefer if (extra) |p| allocator.free(p);
74
75 const filename = if (FLG & FNAME != 0)
76 try source.readUntilDelimiterAlloc(allocator, 0, max_string_len)
77 else
78 null;
7779 errdefer if (filename) |p| allocator.free(p);
7880
79 var comment: ?[]const u8 = null;
80 if (FLG & FCOMMENT != 0) {
81 comment = try source.readUntilDelimiterAlloc(
82 allocator,
83 0,
84 std.math.maxInt(usize),
85 );
86 }
81 const comment = if (FLG & FCOMMENT != 0)
82 try source.readUntilDelimiterAlloc(allocator, 0, max_string_len)
83 else
84 null;
8785 errdefer if (comment) |p| allocator.free(p);
8886
8987 if (FLG & FHCRC != 0) {
......@@ -100,7 +98,9 @@ pub fn GzipStream(comptime ReaderType: type) type {
10098 .info = .{
10199 .filename = filename,
102100 .comment = comment,
101 .extra = extra,
103102 .modification_time = MTIME,
103 .operating_system = OS,
104104 },
105105 .read_amt = 0,
106106 };
......@@ -108,6 +108,8 @@ pub fn GzipStream(comptime ReaderType: type) type {
108108
109109 pub fn deinit(self: *Self) void {
110110 self.inflater.deinit();
111 if (self.info.extra) |extra|
112 self.allocator.free(extra);
111113 if (self.info.filename) |filename|
112114 self.allocator.free(filename);
113115 if (self.info.comment) |comment|