authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2025-08-14 16:08:06-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2025-08-14 16:08:06-07:00
loge252e6c696192729e576fffbd26991bd4b19e434
tree481c8137999a5a650066e2d5229b21b69cf23e76
parent2761cc8be0ef89772a41cb0aaf512ac463aa5c23
parent353cf1f671b9127e7f425aaf3dcba655117ee45b
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #24847 from squeek502/zstd-partial-magic

zstd.Decompress: Treat a partial magic number as a failure

2 files changed, 18 insertions(+), 3 deletions(-)

lib/std/compress/zstd.zig+6
......@@ -121,6 +121,12 @@ test Decompress {
121121 try testExpectDecompress(uncompressed, compressed19);
122122}
123123
124test "partial magic number" {
125 const input_raw =
126 "\x28\xb5\x2f"; // 3 bytes of the 4-byte zstandard frame magic number
127 try testExpectDecompressError(error.BadMagic, input_raw);
128}
129
124130test "zero sized raw block" {
125131 const input_raw =
126132 "\x28\xb5\x2f\xfd" ++ // zstandard frame magic number
lib/std/compress/zstd/Decompress.zig+12-3
......@@ -17,7 +17,6 @@ const State = union(enum) {
1717 new_frame,
1818 in_frame: InFrame,
1919 skipping_frame: usize,
20 end,
2120
2221 const InFrame = struct {
2322 frame: Frame,
......@@ -158,7 +157,18 @@ fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize {
158157
159158 switch (d.state) {
160159 .new_frame => {
161 // Allow error.EndOfStream only on the frame magic.
160 // Only return EndOfStream when there are exactly 0 bytes remaining on the
161 // frame magic. Any partial magic bytes should be considered a failure.
162 in.fill(@sizeOf(Frame.Magic)) catch |err| switch (err) {
163 error.EndOfStream => {
164 if (in.bufferedLen() != 0) {
165 d.err = error.BadMagic;
166 return error.ReadFailed;
167 }
168 return err;
169 },
170 else => |e| return e,
171 };
162172 const magic = try in.takeEnumNonexhaustive(Frame.Magic, .little);
163173 initFrame(d, w.buffer.len, magic) catch |err| {
164174 d.err = err;
......@@ -192,7 +202,6 @@ fn stream(r: *Reader, w: *Writer, limit: Limit) Reader.StreamError!usize {
192202 if (remaining.* == 0) d.state = .new_frame;
193203 return 0;
194204 },
195 .end => return error.EndOfStream,
196205 }
197206}
198207