From 103769f7644eb228e7f12c5e7cf96f0e2d3d6121 Mon Sep 17 00:00:00 2001 From: Folkert Date: Tue, 27 Feb 2024 16:32:19 +0100 Subject: [PATCH] test `Flush::FullFlush` --- libz-rs-sys/src/tests/deflate.rs | 89 ++++++++++++++++++++++++++++++++ zlib-rs/src/deflate.rs | 22 ++++---- 2 files changed, 101 insertions(+), 10 deletions(-) diff --git a/libz-rs-sys/src/tests/deflate.rs b/libz-rs-sys/src/tests/deflate.rs index 6d54083f..1f85ad22 100644 --- a/libz-rs-sys/src/tests/deflate.rs +++ b/libz-rs-sys/src/tests/deflate.rs @@ -1252,3 +1252,92 @@ fn test_deflate_pending() { assert_eq!(err, 0); } } + +/// test deflate() with Flush::Full +#[test] +fn test_flush() { + let config = DeflateConfig::default(); + + const HELLO: &str = "hello, hello!\0"; + let mut compr = [0; 32]; + + unsafe { + let mut strm = MaybeUninit::zeroed(); + + // first validate the config + let err = libz_rs_sys::deflateInit2_( + strm.as_mut_ptr(), + config.level, + config.method as i32, + config.window_bits, + config.mem_level, + config.strategy as i32, + VERSION, + STREAM_SIZE, + ); + assert_eq!(ReturnCode::from(err), ReturnCode::Ok); + + let stream = strm.assume_init_mut(); + + stream.next_in = HELLO.as_ptr() as *mut u8; + stream.next_out = compr.as_mut_ptr(); + + stream.avail_in = 3; + stream.avail_out = compr.len() as _; + + let err = libz_rs_sys::deflate(stream, Flush::FullFlush as i32); + assert_eq!(ReturnCode::from(err), ReturnCode::Ok); + + // force an error in the first compressed block + compr[3] += 1; + stream.avail_in = (HELLO.len() - 3) as _; + + let err = libz_rs_sys::deflate(stream, Flush::Finish as i32); + assert_eq!(ReturnCode::from(err), ReturnCode::StreamEnd); + + let err = libz_rs_sys::deflateEnd(stream); + assert_eq!(ReturnCode::from(err), ReturnCode::Ok); + } + + test_sync(&compr) +} + +// test inflateSync() +fn test_sync(compr: &[u8]) { + let mut uncompr = [0xAA; 32]; + + let mut stream = MaybeUninit::zeroed(); + + let config = InflateConfig::default(); + + unsafe { + let err = libz_rs_sys::inflateInit2_( + stream.as_mut_ptr(), + config.window_bits, + VERSION, + STREAM_SIZE, + ); + assert_eq!(ReturnCode::from(err), ReturnCode::Ok); + + let stream = stream.assume_init_mut(); + + stream.next_in = compr.as_ptr() as *mut u8; + stream.avail_in = 2; // read just the zlib header + + stream.next_out = uncompr.as_mut_ptr(); + stream.avail_out = uncompr.len() as _; + + let err = libz_rs_sys::inflate(stream, Flush::NoFlush as i32); + assert_eq!(ReturnCode::from(err), ReturnCode::Ok); + + stream.avail_in = (compr.len() - 2) as _; // read all compressed data + let err = libz_rs_sys::inflateSync(stream); // but skip the damaged part (at index 3) + assert_eq!(ReturnCode::from(err), ReturnCode::Ok); + + let err = libz_rs_sys::inflate(stream, Flush::Finish as i32); + assert_eq!(ReturnCode::from(err), ReturnCode::StreamEnd); + + let err = libz_rs_sys::inflateEnd(stream); + assert_eq!(ReturnCode::from(err), ReturnCode::Ok); + } +} diff --git a/zlib-rs/src/deflate.rs b/zlib-rs/src/deflate.rs index 41c21a05..9c2a9d28 100644 --- a/zlib-rs/src/deflate.rs +++ b/zlib-rs/src/deflate.rs @@ -2364,19 +2364,21 @@ pub fn deflate(stream: &mut DeflateStream, flush: Flush) -> ReturnCode { todo!() } else if flush != Flush::Block { /* FULL_FLUSH or SYNC_FLUSH */ - // zng_tr_stored_block(s, (char*)0, 0L, 0); + + zng_tr_stored_block(state, 0..0, false); + /* For a full flush, this empty block will be recognized * as a special marker by inflate_sync(). */ - todo!() - // if flush == Flush::FullFlush { - // CLEAR_HASH(state); /* forget history */ - // if (state.lookahead == 0) { - // state.strstart = 0; - // state.block_start = 0; - // state.insert = 0; - // } - // } + if flush == Flush::FullFlush { + state.head.fill(0); // forget history + + if state.lookahead == 0 { + state.strstart = 0; + state.block_start = 0; + state.insert = 0; + } + } } flush_pending(stream);