mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
zstd.Decompress.stream: Fix handling of skippable frames in new_frame state
The previous code assumed that `initFrame` during the `new_frame` state would always result in the `in_frame` state, but that's not always the case. `initFrame` can also result in the `skippable_frame` state, which would lead to access of union field 'in_frame' while field 'skipping_frame' is active. Now, the switch is re-entered with the updated state so either case is handled appropriately. Fixes the crashes from https://github.com/ziglang/zig/issues/24817
This commit is contained in:
parent
e252e6c696
commit
08f0780cb2
@ -156,3 +156,12 @@ test "declared raw literals size too large" {
|
|||||||
// block can't be valid as it is a raw literals block.
|
// block can't be valid as it is a raw literals block.
|
||||||
try testExpectDecompressError(error.MalformedLiteralsSection, input_raw);
|
try testExpectDecompressError(error.MalformedLiteralsSection, input_raw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test "skippable frame" {
|
||||||
|
const input_raw =
|
||||||
|
"\x50\x2a\x4d\x18" ++ // min magic number for a skippable frame
|
||||||
|
"\x02\x00\x00\x00" ++ // number of bytes to skip
|
||||||
|
"\xFF\xFF"; // the bytes that are skipped
|
||||||
|
|
||||||
|
try testExpectDecompress("", input_raw);
|
||||||
|
}
|
||||||
|
|||||||
@ -155,7 +155,7 @@ fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize {
|
|||||||
const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
|
const d: *Decompress = @alignCast(@fieldParentPtr("reader", r));
|
||||||
const in = d.input;
|
const in = d.input;
|
||||||
|
|
||||||
switch (d.state) {
|
state: switch (d.state) {
|
||||||
.new_frame => {
|
.new_frame => {
|
||||||
// Only return EndOfStream when there are exactly 0 bytes remaining on the
|
// Only return EndOfStream when there are exactly 0 bytes remaining on the
|
||||||
// frame magic. Any partial magic bytes should be considered a failure.
|
// frame magic. Any partial magic bytes should be considered a failure.
|
||||||
@ -174,14 +174,7 @@ fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize {
|
|||||||
d.err = err;
|
d.err = err;
|
||||||
return error.ReadFailed;
|
return error.ReadFailed;
|
||||||
};
|
};
|
||||||
return readInFrame(d, w, limit, &d.state.in_frame) catch |err| switch (err) {
|
continue :state d.state;
|
||||||
error.ReadFailed => return error.ReadFailed,
|
|
||||||
error.WriteFailed => return error.WriteFailed,
|
|
||||||
else => |e| {
|
|
||||||
d.err = e;
|
|
||||||
return error.ReadFailed;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
.in_frame => |*in_frame| {
|
.in_frame => |*in_frame| {
|
||||||
return readInFrame(d, w, limit, in_frame) catch |err| switch (err) {
|
return readInFrame(d, w, limit, in_frame) catch |err| switch (err) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user