mirror of
https://github.com/ziglang/zig.git
synced 2025-12-16 03:03:09 +00:00
std.compress.zstandard: validate skippable frame size
This commit is contained in:
parent
98bbd959b0
commit
2134769436
@ -107,19 +107,27 @@ pub fn decodeAlloc(
|
|||||||
/// - `error.UnusedBitSet` if the unused bit of the frame header is set
|
/// - `error.UnusedBitSet` if the unused bit of the frame header is set
|
||||||
/// - `error.EndOfStream` if `src` does not contain a complete frame
|
/// - `error.EndOfStream` if `src` does not contain a complete frame
|
||||||
/// - an error in `block.Error` if there are errors decoding a block
|
/// - an error in `block.Error` if there are errors decoding a block
|
||||||
|
/// - `error.SkippableSizeTooLarge` if the frame is skippable and reports a
|
||||||
|
/// size greater than `src.len`
|
||||||
pub fn decodeFrame(
|
pub fn decodeFrame(
|
||||||
dest: []u8,
|
dest: []u8,
|
||||||
src: []const u8,
|
src: []const u8,
|
||||||
verify_checksum: bool,
|
verify_checksum: bool,
|
||||||
) !ReadWriteCount {
|
) !ReadWriteCount {
|
||||||
var fbs = std.io.fixedBufferStream(src);
|
var fbs = std.io.fixedBufferStream(src);
|
||||||
return switch (try decodeFrameType(fbs.reader())) {
|
switch (try decodeFrameType(fbs.reader())) {
|
||||||
.zstandard => decodeZstandardFrame(dest, src, verify_checksum),
|
.zstandard => return decodeZstandardFrame(dest, src, verify_checksum),
|
||||||
.skippable => ReadWriteCount{
|
.skippable => {
|
||||||
.read_count = try fbs.reader().readIntLittle(u32) + 8,
|
const content_size = try fbs.reader().readIntLittle(u32);
|
||||||
.write_count = 0,
|
if (content_size > std.math.maxInt(usize) - 8) return error.SkippableSizeTooLarge;
|
||||||
|
const read_count = @as(usize, content_size) + 8;
|
||||||
|
if (read_count > src.len) return error.SkippableSizeTooLarge;
|
||||||
|
return ReadWriteCount{
|
||||||
|
.read_count = read_count,
|
||||||
|
.write_count = 0,
|
||||||
|
};
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const DecodeResult = struct {
|
pub const DecodeResult = struct {
|
||||||
@ -150,6 +158,8 @@ pub const DecodedFrame = union(enum) {
|
|||||||
/// - `error.EndOfStream` if `src` does not contain a complete frame
|
/// - `error.EndOfStream` if `src` does not contain a complete frame
|
||||||
/// - `error.OutOfMemory` if `allocator` cannot allocate enough memory
|
/// - `error.OutOfMemory` if `allocator` cannot allocate enough memory
|
||||||
/// - an error in `block.Error` if there are errors decoding a block
|
/// - an error in `block.Error` if there are errors decoding a block
|
||||||
|
/// - `error.SkippableSizeTooLarge` if the frame is skippable and reports a
|
||||||
|
/// size greater than `src.len`
|
||||||
pub fn decodeFrameAlloc(
|
pub fn decodeFrameAlloc(
|
||||||
allocator: Allocator,
|
allocator: Allocator,
|
||||||
src: []const u8,
|
src: []const u8,
|
||||||
@ -159,17 +169,23 @@ pub fn decodeFrameAlloc(
|
|||||||
var fbs = std.io.fixedBufferStream(src);
|
var fbs = std.io.fixedBufferStream(src);
|
||||||
const reader = fbs.reader();
|
const reader = fbs.reader();
|
||||||
const magic = try reader.readIntLittle(u32);
|
const magic = try reader.readIntLittle(u32);
|
||||||
return switch (try frameType(magic)) {
|
switch (try frameType(magic)) {
|
||||||
.zstandard => .{
|
.zstandard => return .{
|
||||||
.zstandard = try decodeZstandardFrameAlloc(allocator, src, verify_checksum, window_size_max),
|
.zstandard = try decodeZstandardFrameAlloc(allocator, src, verify_checksum, window_size_max),
|
||||||
},
|
},
|
||||||
.skippable => .{
|
.skippable => {
|
||||||
.skippable = .{
|
const content_size = try fbs.reader().readIntLittle(u32);
|
||||||
.magic_number = magic,
|
if (content_size > std.math.maxInt(usize) - 8) return error.SkippableSizeTooLarge;
|
||||||
.frame_size = try reader.readIntLittle(u32),
|
const read_count = @as(usize, content_size) + 8;
|
||||||
},
|
if (read_count > src.len) return error.SkippableSizeTooLarge;
|
||||||
|
return .{
|
||||||
|
.skippable = .{
|
||||||
|
.magic_number = magic,
|
||||||
|
.frame_size = content_size,
|
||||||
|
},
|
||||||
|
};
|
||||||
},
|
},
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the frame checksum corresponding to the data fed into `hasher`
|
/// Returns the frame checksum corresponding to the data fed into `hasher`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user