authorgravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-02-12 13:05:34+11:00
committergravatar for 4678790+dweiller@users.noreply.github.comDominic <4678790+dweiller@users.noreply.github.com> 2023-02-20 09:09:06+11:00
log476d2fe1fa917a3b7a92cf155c779eb975c906e6
tree7774215bbe52863c593b2457b543c1a8a5a17ca5
parent373d8ef26edca9d16111ae41f960a44ead6ea2c8

std.compress.zstandard: fix zstandardStream finishing early


1 files changed, 27 insertions(+), 14 deletions(-)

lib/std/compress/zstandard.zig+27-14
......@@ -27,6 +27,7 @@ pub fn ZstandardStream(
2727 literals_buffer: []u8,
2828 sequence_buffer: []u8,
2929 checksum: if (verify_checksum) ?u32 else void,
30 current_frame_decompressed_size: usize,
3031
3132 pub const Error = ReaderType.Error || error{
3233 ChecksumFailure,
......@@ -51,6 +52,7 @@ pub fn ZstandardStream(
5152 .literals_buffer = undefined,
5253 .sequence_buffer = undefined,
5354 .checksum = undefined,
55 .current_frame_decompressed_size = undefined,
5456 };
5557 }
5658
......@@ -113,6 +115,7 @@ pub fn ZstandardStream(
113115 self.frame_context = frame_context;
114116
115117 self.checksum = if (verify_checksum) null else {};
118 self.current_frame_decompressed_size = 0;
116119
117120 self.state = .InFrame;
118121 },
......@@ -134,20 +137,24 @@ pub fn ZstandardStream(
134137 }
135138
136139 pub fn read(self: *Self, buffer: []u8) Error!usize {
137 const initial_count = self.source.bytes_read;
138140 if (buffer.len == 0) return 0;
139 while (self.state == .NewFrame) {
140 self.frameInit() catch |err| switch (err) {
141 error.EndOfStream => return if (self.source.bytes_read == initial_count)
142 0
143 else
144 error.MalformedFrame,
145 error.OutOfMemory => return error.OutOfMemory,
146 else => return error.MalformedFrame,
147 };
148 }
149141
150 return self.readInner(buffer);
142 var size: usize = 0;
143 while (size == 0) {
144 while (self.state == .NewFrame) {
145 const initial_count = self.source.bytes_read;
146 self.frameInit() catch |err| switch (err) {
147 error.EndOfStream => return if (self.source.bytes_read == initial_count)
148 0
149 else
150 error.MalformedFrame,
151 error.OutOfMemory => return error.OutOfMemory,
152 else => return error.MalformedFrame,
153 };
154 }
155 size = try self.readInner(buffer);
156 }
157 return size;
151158 }
152159
153160 fn readInner(self: *Self, buffer: []u8) Error!usize {
......@@ -172,6 +179,7 @@ pub fn ZstandardStream(
172179
173180 if (self.frame_context.hasher_opt) |*hasher| {
174181 const size = self.buffer.len();
182 self.current_frame_decompressed_size += size;
175183 if (size > 0) {
176184 const written_slice = self.buffer.sliceLast(size);
177185 hasher.update(written_slice.first);
......@@ -190,12 +198,17 @@ pub fn ZstandardStream(
190198 }
191199 }
192200 }
201 if (self.frame_context.content_size) |content_size| {
202 if (content_size != self.current_frame_decompressed_size) {
203 return error.MalformedFrame;
204 }
205 }
193206 }
194207 }
195208
196 const decoded_data_len = self.buffer.len();
209 const size = @min(self.buffer.len(), buffer.len);
197210 var count: usize = 0;
198 while (count < decoded_data_len and count < buffer.len) : (count += 1) {
211 while (count < size) : (count += 1) {
199212 buffer[count] = self.buffer.read().?;
200213 }
201214 if (self.state == .LastBlock and self.buffer.len() == 0) {