mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
std.compress.zstandard: fix crashes
This commit is contained in:
parent
a180fcc93d
commit
6e3e72884b
@ -695,11 +695,11 @@ pub fn decodeZStandardFrameAlloc(
|
|||||||
var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined;
|
var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined;
|
||||||
var offset_fse_data: [types.compressed_block.table_size_max.offset]Table.Fse = undefined;
|
var offset_fse_data: [types.compressed_block.table_size_max.offset]Table.Fse = undefined;
|
||||||
|
|
||||||
var block_header = decodeBlockHeader(src[consumed_count..][0..3]);
|
var block_header = try decodeBlockHeaderSlice(src[consumed_count..]);
|
||||||
consumed_count += 3;
|
consumed_count += 3;
|
||||||
var decode_state = DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data);
|
var decode_state = DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data);
|
||||||
while (true) : ({
|
while (true) : ({
|
||||||
block_header = decodeBlockHeader(src[consumed_count..][0..3]);
|
block_header = try decodeBlockHeaderSlice(src[consumed_count..]);
|
||||||
consumed_count += 3;
|
consumed_count += 3;
|
||||||
}) {
|
}) {
|
||||||
if (block_header.block_size > frame_context.block_size_max) return error.BlockSizeOverMaximum;
|
if (block_header.block_size > frame_context.block_size_max) return error.BlockSizeOverMaximum;
|
||||||
@ -737,6 +737,7 @@ const DecodeBlockError = error{
|
|||||||
ReservedBlock,
|
ReservedBlock,
|
||||||
MalformedRleBlock,
|
MalformedRleBlock,
|
||||||
MalformedCompressedBlock,
|
MalformedCompressedBlock,
|
||||||
|
EndOfStream,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Convenience wrapper for decoding all blocks in a frame; see `decodeBlock()`.
|
/// Convenience wrapper for decoding all blocks in a frame; see `decodeBlock()`.
|
||||||
@ -751,13 +752,13 @@ pub fn decodeFrameBlocks(
|
|||||||
var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined;
|
var match_fse_data: [types.compressed_block.table_size_max.match]Table.Fse = undefined;
|
||||||
var offset_fse_data: [types.compressed_block.table_size_max.offset]Table.Fse = undefined;
|
var offset_fse_data: [types.compressed_block.table_size_max.offset]Table.Fse = undefined;
|
||||||
|
|
||||||
var block_header = decodeBlockHeader(src[0..3]);
|
var block_header = try decodeBlockHeaderSlice(src);
|
||||||
var bytes_read: usize = 3;
|
var bytes_read: usize = 3;
|
||||||
defer consumed_count.* += bytes_read;
|
defer consumed_count.* += bytes_read;
|
||||||
var decode_state = DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data);
|
var decode_state = DecodeState.init(&literal_fse_data, &match_fse_data, &offset_fse_data);
|
||||||
var written_count: usize = 0;
|
var written_count: usize = 0;
|
||||||
while (true) : ({
|
while (true) : ({
|
||||||
block_header = decodeBlockHeader(src[bytes_read..][0..3]);
|
block_header = try decodeBlockHeaderSlice(src[bytes_read..]);
|
||||||
bytes_read += 3;
|
bytes_read += 3;
|
||||||
}) {
|
}) {
|
||||||
const written_size = try decodeBlock(
|
const written_size = try decodeBlock(
|
||||||
@ -847,6 +848,7 @@ pub fn decodeBlock(
|
|||||||
|
|
||||||
bytes_read += bit_stream_bytes.len;
|
bytes_read += bit_stream_bytes.len;
|
||||||
}
|
}
|
||||||
|
if (bytes_read != block_size) return error.MalformedCompressedBlock;
|
||||||
|
|
||||||
if (decode_state.literal_written_count < literals.header.regenerated_size) {
|
if (decode_state.literal_written_count < literals.header.regenerated_size) {
|
||||||
const len = literals.header.regenerated_size - decode_state.literal_written_count;
|
const len = literals.header.regenerated_size - decode_state.literal_written_count;
|
||||||
@ -855,7 +857,6 @@ pub fn decodeBlock(
|
|||||||
bytes_written += len;
|
bytes_written += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(bytes_read == block_header.block_size);
|
|
||||||
consumed_count.* += bytes_read;
|
consumed_count.* += bytes_read;
|
||||||
return bytes_written;
|
return bytes_written;
|
||||||
},
|
},
|
||||||
@ -931,6 +932,7 @@ pub fn decodeBlockRingBuffer(
|
|||||||
|
|
||||||
bytes_read += bit_stream_bytes.len;
|
bytes_read += bit_stream_bytes.len;
|
||||||
}
|
}
|
||||||
|
if (bytes_read != block_size) return error.MalformedCompressedBlock;
|
||||||
|
|
||||||
if (decode_state.literal_written_count < literals.header.regenerated_size) {
|
if (decode_state.literal_written_count < literals.header.regenerated_size) {
|
||||||
const len = literals.header.regenerated_size - decode_state.literal_written_count;
|
const len = literals.header.regenerated_size - decode_state.literal_written_count;
|
||||||
@ -939,7 +941,6 @@ pub fn decodeBlockRingBuffer(
|
|||||||
bytes_written += len;
|
bytes_written += len;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(bytes_read == block_header.block_size);
|
|
||||||
consumed_count.* += bytes_read;
|
consumed_count.* += bytes_read;
|
||||||
if (bytes_written > block_size_max) return error.BlockSizeOverMaximum;
|
if (bytes_written > block_size_max) return error.BlockSizeOverMaximum;
|
||||||
return bytes_written;
|
return bytes_written;
|
||||||
@ -1101,6 +1102,11 @@ pub fn decodeBlockHeader(src: *const [3]u8) frame.ZStandard.Block.Header {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn decodeBlockHeaderSlice(src: []const u8) error{EndOfStream}!frame.ZStandard.Block.Header {
|
||||||
|
if (src.len < 3) return error.EndOfStream;
|
||||||
|
return decodeBlockHeader(src[0..3]);
|
||||||
|
}
|
||||||
|
|
||||||
/// Decode a `LiteralsSection` from `src`, incrementing `consumed_count` by the
|
/// Decode a `LiteralsSection` from `src`, incrementing `consumed_count` by the
|
||||||
/// number of bytes the section uses.
|
/// number of bytes the section uses.
|
||||||
///
|
///
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user