zig

fork of https://codeberg.org/ziglang/zig
Log | Tree | Refs | README | LICENSE

commit e361740669e95b198cfbbcb7a600edc3a0de273a (tree)
parent 8d17e90fcd3c54da5a271ad13eb114822c22d8da
Author: Veikka Tuominen <git@vexu.eu>
Date:   Sun,  4 Dec 2022 14:32:25 +0200

Merge pull request #13142 from mllken/gzip-safety

gzip: add missing header fields and bounds for header parsing
Diffstat:
Mlib/std/compress/gzip.zig | 48+++++++++++++++++++++++++-----------------------
1 file changed, 25 insertions(+), 23 deletions(-)

diff --git a/lib/std/compress/gzip.zig b/lib/std/compress/gzip.zig @@ -15,6 +15,8 @@ const FEXTRA = 1 << 2; const FNAME = 1 << 3; const FCOMMENT = 1 << 4; +const max_string_len = 1024; + pub fn GzipStream(comptime ReaderType: type) type { return struct { const Self = @This(); @@ -31,9 +33,11 @@ pub fn GzipStream(comptime ReaderType: type) type { read_amt: usize, info: struct { + extra: ?[]const u8, filename: ?[]const u8, comment: ?[]const u8, modification_time: u32, + operating_system: u8, }, fn init(allocator: mem.Allocator, source: ReaderType) !Self { @@ -57,33 +61,27 @@ pub fn GzipStream(comptime ReaderType: type) type { // Operating system where the compression took place const OS = header[9]; _ = XFL; - _ = OS; - if (FLG & FEXTRA != 0) { - // Skip the extra data, we could read and expose it to the user - // if somebody needs it. + const extra = if (FLG & FEXTRA != 0) blk: { const len = try source.readIntLittle(u16); - try source.skipBytes(len, .{}); - } - - var filename: ?[]const u8 = null; - if (FLG & FNAME != 0) { - filename = try source.readUntilDelimiterAlloc( - allocator, - 0, - std.math.maxInt(usize), - ); - } + const tmp_buf = try allocator.alloc(u8, len); + errdefer allocator.free(tmp_buf); + + try source.readNoEof(tmp_buf); + break :blk tmp_buf; + } else null; + errdefer if (extra) |p| allocator.free(p); + + const filename = if (FLG & FNAME != 0) + try source.readUntilDelimiterAlloc(allocator, 0, max_string_len) + else + null; errdefer if (filename) |p| allocator.free(p); - var comment: ?[]const u8 = null; - if (FLG & FCOMMENT != 0) { - comment = try source.readUntilDelimiterAlloc( - allocator, - 0, - std.math.maxInt(usize), - ); - } + const comment = if (FLG & FCOMMENT != 0) + try source.readUntilDelimiterAlloc(allocator, 0, max_string_len) + else + null; errdefer if (comment) |p| allocator.free(p); if (FLG & FHCRC != 0) { @@ -100,7 +98,9 @@ pub fn GzipStream(comptime ReaderType: type) type { .info = .{ .filename = filename, .comment = comment, + .extra = extra, .modification_time = MTIME, + .operating_system = OS, }, .read_amt = 0, }; @@ -108,6 +108,8 @@ pub fn GzipStream(comptime ReaderType: type) type { pub fn deinit(self: *Self) void { self.inflater.deinit(); + if (self.info.extra) |extra| + self.allocator.free(extra); if (self.info.filename) |filename| self.allocator.free(filename); if (self.info.comment) |comment|