Skip to content

Commit 5206d91

Browse files
committed
add test_dict_inflate
1 parent 5b01d64 commit 5206d91

File tree

4 files changed

+148
-2
lines changed

4 files changed

+148
-2
lines changed

libz-rs-sys/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1797,6 +1797,13 @@ pub const extern "C" fn zlibCompileFlags() -> c_ulong {
17971797
///
17981798
/// * [`Z_OK`] if success
17991799
/// * [`Z_STREAM_ERROR`] if the stream state is inconsistent
1800+
///
1801+
/// # Safety
1802+
///
1803+
/// - `dictionary` must `NULL` or writable for the dictionary length (`32768` is always enough)
1804+
/// - `dictLength` must `NULL` or satisfy the requirements of [`pointer::as_mut`]
1805+
///
1806+
/// [`pointer::as_mut`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.as_mut
18001807
#[cfg_attr(feature = "export-symbols", export_name = prefix!(inflateGetDictionary))]
18011808
pub unsafe extern "C-unwind" fn inflateGetDictionary(
18021809
strm: *const z_stream,
@@ -1835,6 +1842,13 @@ pub unsafe extern "C-unwind" fn inflateGetDictionary(
18351842
///
18361843
/// * [`Z_OK`] if success
18371844
/// * [`Z_STREAM_ERROR`] if the stream state is inconsistent
1845+
///
1846+
/// # Safety
1847+
///
1848+
/// - `dictionary` must `NULL` or writable for the dictionary length (`32768` is always enough)
1849+
/// - `dictLength` must `NULL` or satisfy the requirements of [`pointer::as_mut`]
1850+
///
1851+
/// [`pointer::as_mut`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.as_mut
18381852
#[cfg_attr(feature = "export-symbols", export_name = prefix!(deflateGetDictionary))]
18391853
pub unsafe extern "C-unwind" fn deflateGetDictionary(
18401854
strm: *const z_stream,

test-libz-rs-sys/src/deflate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ use libz_sys as libz_ng_sys;
66
use core::ffi::{c_char, c_int, c_uint, c_ulong, CStr};
77

88
use libz_rs_sys::{
9-
deflate, deflateEnd, deflateInit2_, deflateInit_, inflate, inflateEnd, inflateInit2_,
10-
Z_DEFLATED, Z_FILTERED, Z_FINISH, Z_NO_FLUSH,
9+
deflate, deflateEnd, deflateInit2_, inflate, inflateEnd, inflateInit2_, Z_DEFLATED, Z_FILTERED,
10+
Z_NO_FLUSH,
1111
};
1212
use zlib_rs::{
1313
c_api::Z_BEST_COMPRESSION,

test-libz-rs-sys/src/inflate.rs

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2279,3 +2279,128 @@ fn codes_used() {
22792279
});
22802280
}
22812281
}
2282+
2283+
#[test]
2284+
fn test_dict_inflate() {
2285+
// Maximum dictionary size, according to inflateGetDictionary() description.
2286+
const MAX_DICTIONARY_SIZE: usize = 32768;
2287+
2288+
let mut dictionary = *b"hello\0";
2289+
let mut hello = *b"hello\0";
2290+
2291+
let (compr, dict_id) = assert_eq_rs_ng!({
2292+
let mut compr = [0u8; 1024];
2293+
2294+
let mut strm = MaybeUninit::zeroed();
2295+
2296+
let ret = unsafe {
2297+
deflateInit_(
2298+
strm.as_mut_ptr(),
2299+
Z_BEST_COMPRESSION,
2300+
zlibVersion(),
2301+
core::mem::size_of::<z_stream>() as _,
2302+
)
2303+
};
2304+
2305+
let c_stream = unsafe { strm.assume_init_mut() };
2306+
2307+
assert_eq!(ReturnCode::from(ret), ReturnCode::Ok);
2308+
2309+
let err =
2310+
unsafe { deflateSetDictionary(c_stream, dictionary.as_ptr(), dictionary.len() as _) };
2311+
assert_eq!(ReturnCode::from(err), ReturnCode::Ok);
2312+
2313+
let dict_id = c_stream.adler;
2314+
c_stream.avail_out = compr.len() as _;
2315+
c_stream.next_out = compr.as_mut_ptr();
2316+
2317+
c_stream.avail_in = hello.len() as _;
2318+
c_stream.next_in = hello.as_mut_ptr();
2319+
2320+
let err = unsafe { deflate(c_stream, Z_FINISH) };
2321+
assert_eq!(ReturnCode::from(err), ReturnCode::StreamEnd);
2322+
2323+
if err != Z_STREAM_END {
2324+
panic!("deflate should report Z_STREAM_END\n");
2325+
}
2326+
let err = unsafe { deflateEnd(c_stream) };
2327+
assert_eq!(ReturnCode::from(err), ReturnCode::Ok);
2328+
2329+
(compr, dict_id)
2330+
});
2331+
2332+
assert_eq_rs_ng!({
2333+
let mut compr = compr;
2334+
let mut uncompr = *b"garbage garbage garbage\0";
2335+
2336+
let mut stream = MaybeUninit::<z_stream>::zeroed();
2337+
2338+
let err = unsafe {
2339+
inflateInit_(
2340+
stream.as_mut_ptr(),
2341+
zlibVersion(),
2342+
core::mem::size_of::<z_stream>() as c_int,
2343+
)
2344+
};
2345+
assert_eq!(ReturnCode::from(err), ReturnCode::Ok);
2346+
2347+
let d_stream = stream.assume_init_mut();
2348+
2349+
d_stream.adler = 0;
2350+
d_stream.avail_in = compr.len() as _;
2351+
d_stream.next_in = compr.as_mut_ptr();
2352+
2353+
d_stream.avail_out = uncompr.len() as _;
2354+
d_stream.next_out = uncompr.as_mut_ptr();
2355+
2356+
let mut check_dictionary = [0i8; MAX_DICTIONARY_SIZE];
2357+
2358+
loop {
2359+
let mut err = unsafe { inflate(d_stream, Z_NO_FLUSH) };
2360+
2361+
if err == Z_STREAM_END {
2362+
break;
2363+
}
2364+
2365+
if err == Z_NEED_DICT {
2366+
if d_stream.adler != dict_id {
2367+
panic!("unexpected dictionary");
2368+
}
2369+
err = unsafe {
2370+
inflateSetDictionary(d_stream, dictionary.as_mut_ptr(), dictionary.len() as _)
2371+
};
2372+
}
2373+
2374+
assert_eq!(ReturnCode::from(err), ReturnCode::Ok);
2375+
}
2376+
2377+
let mut check_dictionary_len = 0;
2378+
let err = unsafe {
2379+
inflateGetDictionary(d_stream, core::ptr::null_mut(), &mut check_dictionary_len)
2380+
};
2381+
assert_eq!(ReturnCode::from(err), ReturnCode::Ok);
2382+
2383+
if (check_dictionary_len as usize) < dictionary.len() {
2384+
panic!("bad dictionary length");
2385+
}
2386+
2387+
let err = unsafe {
2388+
inflateGetDictionary(
2389+
d_stream,
2390+
check_dictionary.as_mut_ptr().cast(),
2391+
&mut check_dictionary_len,
2392+
)
2393+
};
2394+
assert_eq!(ReturnCode::from(err), ReturnCode::Ok);
2395+
2396+
assert_eq!(
2397+
dictionary,
2398+
&check_dictionary.map(|c| c as u8)[..dictionary.len()]
2399+
);
2400+
2401+
let err = unsafe { inflateEnd(d_stream) };
2402+
assert_eq!(ReturnCode::from(err), ReturnCode::Ok);
2403+
2404+
assert_eq!(uncompr[..hello.len()], hello);
2405+
});
2406+
}

test-libz-rs-sys/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,13 @@ macro_rules! assert_eq_rs_ng {
3232
dictionary: *mut core::ffi::c_uchar,
3333
dictLength: *mut core::ffi::c_uint,
3434
) -> core::ffi::c_int;
35+
36+
#[allow(unused)]
37+
fn inflateGetDictionary(
38+
strm: *const z_stream,
39+
dictionary: *mut core::ffi::c_uchar,
40+
dictLength: *mut core::ffi::c_uint,
41+
) -> core::ffi::c_int;
3542
}
3643

3744
$tt

0 commit comments

Comments
 (0)