Merge pull request #13142 from mllken/gzip-safety

gzip: add missing header fields and bounds for header parsing
This commit is contained in:
Veikka Tuominen 2022-12-04 14:32:25 +02:00 committed by GitHub
commit e361740669
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -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, .{});
}
const tmp_buf = try allocator.alloc(u8, len);
errdefer allocator.free(tmp_buf);
var filename: ?[]const u8 = null;
if (FLG & FNAME != 0) {
filename = try source.readUntilDelimiterAlloc(
allocator,
0,
std.math.maxInt(usize),
);
}
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|