mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-01 05:37:23 -06:00
Merge pull request #4945 from dotCooCoo/fix/ai-zstd-trailing-zero
.ai import: a Zstandard frame that ends in a zero byte keeps it
This commit is contained in:
@@ -158,11 +158,11 @@ impl Codec {
|
||||
flate2::read::ZlibDecoder::new(data).take(max + 1).read_to_end(&mut out).map_err(|_| damaged("its zlib compression"))?;
|
||||
}
|
||||
Codec::Zstd => {
|
||||
// The data may be several frames one after the other, padded with zeros.
|
||||
let end = data.iter().rposition(|b| *b != 0).map_or(0, |i| i + 1);
|
||||
let mut src = data.get(..end).unwrap_or_default();
|
||||
// The data may be several frames one after the other, padded with zeros. A frame
|
||||
// can itself end in a zero byte, so the padding is what is left after the last frame.
|
||||
let mut src = data;
|
||||
let mut frames = 0usize;
|
||||
while !src.is_empty() {
|
||||
while src.iter().any(|b| *b != 0) {
|
||||
frames += 1;
|
||||
if frames > MAX_FRAMES {
|
||||
return Err(damaged("its Zstandard compression"));
|
||||
|
||||
@@ -1472,6 +1472,19 @@ fn many_zstandard_frames_are_read_in_one_pass_and_capped() {
|
||||
assert!(started.elapsed() < std::time::Duration::from_secs(20), "{:?}", started.elapsed());
|
||||
}
|
||||
|
||||
/// A Zstandard frame that ends in a zero byte keeps it: only the zeros after the last frame are
|
||||
/// padding.
|
||||
#[test]
|
||||
fn a_zstandard_frame_ending_in_a_zero_byte_is_read_whole() {
|
||||
// Magic number, a single-segment header with a 1-byte content size of 3, and one raw block
|
||||
// (last, 3 bytes) holding `ab` and a zero byte.
|
||||
let frame = [0x28, 0xB5, 0x2F, 0xFD, 0x20, 3, 0x19, 0, 0, b'a', b'b', 0];
|
||||
for padding in [0, 64] {
|
||||
let raw = [&b"%AI24_ZStandard_Data"[..], &frame, &frame, &vec![0; padding]].concat();
|
||||
assert_eq!(decode_private(&raw).unwrap(), b"ab\0ab\0");
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn closing_brackets_without_their_opening_dont_rescan_the_stack() {
|
||||
let n = 200_000;
|
||||
|
||||
Reference in New Issue
Block a user