| ... | ... | @@ -107,19 +107,27 @@ pub fn decodeAlloc( |
| 107 | 107 | /// - `error.UnusedBitSet` if the unused bit of the frame header is set |
| 108 | 108 | /// - `error.EndOfStream` if `src` does not contain a complete frame |
| 109 | 109 | /// - an error in `block.Error` if there are errors decoding a block |
| 110 | /// - `error.SkippableSizeTooLarge` if the frame is skippable and reports a |
| 111 | /// size greater than `src.len` |
| 110 | 112 | pub fn decodeFrame( |
| 111 | 113 | dest: []u8, |
| 112 | 114 | src: []const u8, |
| 113 | 115 | verify_checksum: bool, |
| 114 | 116 | ) !ReadWriteCount { |
| 115 | 117 | var fbs = std.io.fixedBufferStream(src); |
| 116 | | return switch (try decodeFrameType(fbs.reader())) { |
| 117 | | .zstandard => decodeZstandardFrame(dest, src, verify_checksum), |
| 118 | | .skippable => ReadWriteCount{ |
| 119 | | .read_count = try fbs.reader().readIntLittle(u32) + 8, |
| 120 | | .write_count = 0, |
| 118 | switch (try decodeFrameType(fbs.reader())) { |
| 119 | .zstandard => return decodeZstandardFrame(dest, src, verify_checksum), |
| 120 | .skippable => { |
| 121 | const content_size = try fbs.reader().readIntLittle(u32); |
| 122 | if (content_size > std.math.maxInt(usize) - 8) return error.SkippableSizeTooLarge; |
| 123 | const read_count = @as(usize, content_size) + 8; |
| 124 | if (read_count > src.len) return error.SkippableSizeTooLarge; |
| 125 | return ReadWriteCount{ |
| 126 | .read_count = read_count, |
| 127 | .write_count = 0, |
| 128 | }; |
| 121 | 129 | }, |
| 122 | | }; |
| 130 | } |
| 123 | 131 | } |
| 124 | 132 | |
| 125 | 133 | pub const DecodeResult = struct { |
| ... | ... | @@ -150,6 +158,8 @@ pub const DecodedFrame = union(enum) { |
| 150 | 158 | /// - `error.EndOfStream` if `src` does not contain a complete frame |
| 151 | 159 | /// - `error.OutOfMemory` if `allocator` cannot allocate enough memory |
| 152 | 160 | /// - an error in `block.Error` if there are errors decoding a block |
| 161 | /// - `error.SkippableSizeTooLarge` if the frame is skippable and reports a |
| 162 | /// size greater than `src.len` |
| 153 | 163 | pub fn decodeFrameAlloc( |
| 154 | 164 | allocator: Allocator, |
| 155 | 165 | src: []const u8, |
| ... | ... | @@ -159,17 +169,23 @@ pub fn decodeFrameAlloc( |
| 159 | 169 | var fbs = std.io.fixedBufferStream(src); |
| 160 | 170 | const reader = fbs.reader(); |
| 161 | 171 | const magic = try reader.readIntLittle(u32); |
| 162 | | return switch (try frameType(magic)) { |
| 163 | | .zstandard => .{ |
| 172 | switch (try frameType(magic)) { |
| 173 | .zstandard => return .{ |
| 164 | 174 | .zstandard = try decodeZstandardFrameAlloc(allocator, src, verify_checksum, window_size_max), |
| 165 | 175 | }, |
| 166 | | .skippable => .{ |
| 167 | | .skippable = .{ |
| 168 | | .magic_number = magic, |
| 169 | | .frame_size = try reader.readIntLittle(u32), |
| 170 | | }, |
| 176 | .skippable => { |
| 177 | const content_size = try fbs.reader().readIntLittle(u32); |
| 178 | if (content_size > std.math.maxInt(usize) - 8) return error.SkippableSizeTooLarge; |
| 179 | const read_count = @as(usize, content_size) + 8; |
| 180 | if (read_count > src.len) return error.SkippableSizeTooLarge; |
| 181 | return .{ |
| 182 | .skippable = .{ |
| 183 | .magic_number = magic, |
| 184 | .frame_size = content_size, |
| 185 | }, |
| 186 | }; |
| 171 | 187 | }, |
| 172 | | }; |
| 188 | } |
| 173 | 189 | } |
| 174 | 190 | |
| 175 | 191 | /// Returns the frame checksum corresponding to the data fed into `hasher` |