Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions lib/std/compress/zstandard.zig
Original file line number Diff line number Diff line change
Expand Up @@ -289,3 +289,22 @@ test "zero sized block" {
try expectEqualDecodedStreaming("", input_raw);
try expectEqualDecodedStreaming("", input_rle);
}

test "declared raw literals size too large" {
const input_raw =
"\x28\xb5\x2f\xfd" ++ // zstandard frame magic number
"\x00\x00" ++ // frame header: everything unset, window descriptor zero
"\x95\x00\x00" ++ // block header with: last_block set, block_type compressed, block_size 18
"\xbc\xf3\xae" ++ // literals section header with: type raw, size_format 3, regenerated_size 716603
"\xa5\x9f\xe3"; // some bytes of literal content - the content is shorter than regenerated_size

// Note that the regenerated_size in the above input is larger than block maximum size, so the
// block can't be valid as it is a raw literals block.

var fbs = std.io.fixedBufferStream(input_raw);
var window: [1024]u8 = undefined;
var stream = decompressor(fbs.reader(), .{ .window_buffer = &window });

var buf: [1024]u8 = undefined;
try std.testing.expectError(error.MalformedBlock, stream.read(&buf));
}
1 change: 1 addition & 0 deletions lib/std/compress/zstandard/decode/block.zig
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,7 @@ pub fn decodeLiteralsSection(
const header = try decodeLiteralsHeader(source);
switch (header.block_type) {
.raw => {
if (buffer.len < header.regenerated_size) return error.LiteralsBufferTooSmall;
try source.readNoEof(buffer[0..header.regenerated_size]);
return LiteralsSection{
.header = header,
Expand Down
4 changes: 2 additions & 2 deletions lib/std/compress/zstandard/decompress.zig
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ pub const FrameContext = struct {
/// - `error.WindowSizeUnknown` if the frame does not have a valid window
/// size
/// - `error.WindowTooLarge` if the window size is larger than
/// `window_size_max`
/// `window_size_max` or `std.math.intMax(usize)`
/// - `error.ContentSizeTooLarge` if the frame header indicates a content
/// size larger than `std.math.maxInt(usize)`
pub fn init(
Expand All @@ -395,7 +395,7 @@ pub const FrameContext = struct {
const window_size = if (window_size_raw > window_size_max)
return error.WindowTooLarge
else
@as(usize, @intCast(window_size_raw));
std.math.cast(usize, window_size_raw) orelse return error.WindowTooLarge;

const should_compute_checksum =
frame_header.descriptor.content_checksum_flag and verify_checksum;
Expand Down