Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update zlib-ng version 2.2.3 #282

Merged
merged 4 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ opt-level = 1 # required for the tail calls in inflate to optimize

[workspace.dependencies]
libloading = "0.8.1"
libz-sys = { version = "1.1.19", default-features = false, features = ["zlib-ng"] } # use libz-ng in libz compat mode
libz-sys = { version = "1.1.21", default-features = false, features = ["zlib-ng"] } # use libz-ng in libz compat mode
arbitrary = { version = "1.0" }
quickcheck = { version = "1.0.3", default-features = false, features = [] }

Expand Down
2 changes: 1 addition & 1 deletion fuzz/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ features = ["arbitrary-derive"]

[dependencies]
libc = "0.2.151"
libz-ng-sys = "1.1.12"
libz-ng-sys = "1.1.21"
libloading = "0.8.1"
crc32fast = "1.3.2"
rstest = "0.23.0"
Expand Down
77 changes: 26 additions & 51 deletions test-libz-rs-sys/src/deflate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1815,14 +1815,9 @@ mod fuzz_based_tests {
// depending on the algorithm that can give different results. Note that in this case, the
// output of aarch64 and x86_64 do line up with the current aarch64 hashing approach.

let output_other = &[
24, 149, 99, 96, 102, 24, 104, 160, 7, 38, 57, 96, 92, 117, 6, 14, 6, 38, 60, 202, 65,
14, 86, 99, 208, 3, 3, 6, 67, 6, 38, 22, 122, 184, 17, 2, 40, 119, 41, 84, 175, 26, 0,
172, 56, 3, 232,
];

// longest_match does not perform unaligned 32-bit reads/writes on s390x
let output_s390x = &[
// historical note: previously we used the crc32 hardware instructions, but later versions
// of zlib-ng stopped doing that (the dispatch cost was too high), and we followed suit.
let output = &[
24, 149, 99, 96, 102, 24, 104, 160, 7, 38, 57, 96, 92, 117, 6, 14, 6, 38, 60, 202, 65,
14, 86, 99, 208, 3, 3, 6, 67, 6, 38, 22, 58, 56, 17, 10, 40, 119, 41, 84, 175, 26, 0,
172, 56, 3, 232,
Expand Down Expand Up @@ -1852,22 +1847,13 @@ mod fuzz_based_tests {
mem_level: 2,
strategy: Strategy::Default,
},
if cfg!(any(miri, target_arch = "s390x", target_family = "wasm")) {
output_s390x
} else {
output_other
},
output,
)
}

#[test]
#[cfg_attr(
target_family = "wasm",
ignore = "zlib-ng compresses differently on wasm"
)]
fn longest_match_difference() {
// the output on aarch64 and x86_64: fully featured modern targets
let output_other = &[
let output = &[
24, 87, 83, 81, 97, 100, 96, 96, 228, 98, 0, 3, 123, 6, 6, 77, 21, 16, 67, 5, 36, 10,
102, 73, 139, 67, 164, 24, 194, 64, 32, 144, 75, 55, 16, 5, 248, 65, 65, 52, 152, 116,
99, 100, 96, 96, 16, 98, 96, 151, 241, 243, 243, 11, 12, 52, 128, 41, 2, 153, 206, 6,
Expand All @@ -1877,31 +1863,6 @@ mod fuzz_based_tests {
82,
];

// longest_match does not perform unaligned 64-bit reads/writes on i686
let output_i686 = &[
24, 87, 83, 81, 97, 100, 96, 96, 228, 98, 0, 3, 123, 6, 6, 77, 21, 16, 67, 5, 36, 10,
102, 73, 139, 67, 164, 24, 194, 64, 32, 144, 75, 55, 16, 5, 248, 65, 65, 52, 152, 116,
99, 100, 96, 96, 16, 98, 96, 151, 241, 243, 243, 11, 12, 52, 128, 41, 2, 153, 206, 6,
50, 21, 106, 20, 20, 56, 66, 40, 5, 48, 169, 98, 13, 166, 4, 24, 98, 25, 20, 192, 138,
173, 37, 24, 184, 32, 64, 65, 26, 68, 50, 112, 128, 57, 26, 32, 83, 224, 134, 73, 162,
154, 8, 7, 14, 40, 60, 78, 20, 30, 8, 48, 97, 136, 48, 48, 128, 125, 128, 36, 0, 0,
125, 74, 22, 82,
];

// longest_match does not perform unaligned 32-bit reads/writes on s390x
let output_s390x = &[
24, 87, 83, 81, 97, 100, 96, 96, 228, 98, 0, 3, 123, 6, 6, 77, 21, 16, 67, 5, 36, 10,
102, 73, 139, 67, 164, 24, 194, 64, 32, 144, 75, 55, 16, 5, 248, 65, 65, 52, 152, 116,
99, 100, 96, 96, 16, 98, 96, 151, 241, 243, 243, 11, 12, 52, 128, 41, 2, 153, 206, 6,
50, 21, 106, 20, 20, 56, 66, 40, 5, 48, 169, 98, 13, 166, 4, 24, 98, 25, 20, 192, 138,
173, 37, 24, 184, 32, 64, 65, 26, 68, 50, 112, 128, 57, 26, 32, 83, 224, 134, 73, 66,
140, 192, 0, 14, 40, 60, 78, 20, 30, 8, 48, 97, 136, 48, 48, 128, 125, 128, 36, 0, 0,
125, 74, 22, 82,
];

assert_ne!(output_i686.as_slice(), output_other.as_slice());
assert_ne!(output_i686.as_slice(), output_s390x.as_slice());

fuzz_based_test(
&[
36, 36, 1, 0, 0, 1, 10, 0, 0, 0, 0, 0, 0, 63, 0, 0, 41, 36, 0, 0, 0, 0, 36, 36, 1,
Expand All @@ -1924,13 +1885,27 @@ mod fuzz_based_tests {
mem_level: 6,
strategy: Strategy::Default,
},
if cfg!(target_arch = "x86") {
output_i686
} else if cfg!(target_arch = "s390x") {
output_s390x
} else {
output_other
},
output,
)
}

// a change introduced in [commit].
// make sure we match the new behavior, and throw an error if the test suite runs with older
// versions
//
// [commit]: https://github.com/zlib-ng/zlib-ng/commit/322753f36e833343ae030e499564691da15eef32
#[test]
fn deflate_medium_bypass() {
let mut input = [0u8; 268];
input[0] = 0x16;
input[263] = 0x5;

fuzz_based_test(
&input,
DeflateConfig::default(),
&[
120, 156, 19, 99, 24, 5, 12, 12, 12, 172, 32, 18, 0, 24, 45, 0, 28,
],
)
}
}
Expand Down
37 changes: 3 additions & 34 deletions zlib-rs/src/deflate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use crate::{

use self::{
algorithm::CONFIGURATION_TABLE,
hash_calc::{Crc32HashCalc, HashCalcVariant, RollHashCalc, StandardHashCalc},
hash_calc::{HashCalcVariant, RollHashCalc, StandardHashCalc},
pending::Pending,
trees_tbl::STATIC_LTREE,
window::Window,
Expand Down Expand Up @@ -1388,9 +1388,6 @@ impl<'a> State<'a> {
pub(crate) fn update_hash(&self, h: u32, val: u32) -> u32 {
match self.hash_calc_variant {
HashCalcVariant::Standard => StandardHashCalc::update_hash(h, val),
// SAFETY: self.hash_calc_variant is set by HashCalcVariant::for_max_chain_length,
// which avoids choosing Crc32 if the system doesn't have support.
HashCalcVariant::Crc32 => unsafe { Crc32HashCalc::update_hash(h, val) },
HashCalcVariant::Roll => RollHashCalc::update_hash(h, val),
}
}
Expand All @@ -1399,9 +1396,6 @@ impl<'a> State<'a> {
pub(crate) fn quick_insert_string(&mut self, string: usize) -> u16 {
match self.hash_calc_variant {
HashCalcVariant::Standard => StandardHashCalc::quick_insert_string(self, string),
// SAFETY: self.hash_calc_variant is set by HashCalcVariant::for_max_chain_length,
// which avoids choosing Crc32 if the system doesn't have support.
HashCalcVariant::Crc32 => unsafe { Crc32HashCalc::quick_insert_string(self, string) },
HashCalcVariant::Roll => RollHashCalc::quick_insert_string(self, string),
}
}
Expand All @@ -1410,9 +1404,6 @@ impl<'a> State<'a> {
pub(crate) fn insert_string(&mut self, string: usize, count: usize) {
match self.hash_calc_variant {
HashCalcVariant::Standard => StandardHashCalc::insert_string(self, string, count),
// SAFETY: self.hash_calc_variant is set by HashCalcVariant::for_max_chain_length,
// which avoids choosing Crc32 if the system doesn't have support.
HashCalcVariant::Crc32 => unsafe { Crc32HashCalc::insert_string(self, string, count) },
HashCalcVariant::Roll => RollHashCalc::insert_string(self, string, count),
}
}
Expand Down Expand Up @@ -4196,35 +4187,14 @@ mod test {
strategy: Strategy::Default,
};

let crc32 = [
24, 149, 99, 96, 96, 96, 96, 208, 6, 17, 112, 138, 129, 193, 128, 1, 29, 24, 50, 208,
1, 200, 146, 169, 79, 24, 74, 59, 96, 147, 52, 71, 22, 70, 246, 88, 26, 94, 80, 128,
83, 6, 162, 219, 144, 76, 183, 210, 5, 8, 67, 105, 7, 108, 146, 230, 216, 133, 145,
129, 22, 3, 3, 131, 17, 3, 0, 3, 228, 25, 128,
];

let other = [
let expected = [
24, 149, 99, 96, 96, 96, 96, 208, 6, 17, 112, 138, 129, 193, 128, 1, 29, 24, 50, 208,
1, 200, 146, 169, 79, 24, 74, 59, 96, 147, 52, 71, 22, 70, 246, 88, 26, 94, 80, 128,
83, 6, 162, 219, 144, 76, 183, 210, 5, 8, 67, 105, 36, 159, 35, 128, 57, 118, 97, 100,
160, 197, 192, 192, 96, 196, 0, 0, 3, 228, 25, 128,
];

// the output is slightly different based on what hashing algorithm is used
match HashCalcVariant::for_compression_level(config.level as usize) {
HashCalcVariant::Crc32 => {
// the aarch64 hashing algorithm is different from the standard algorithm, but in
// this case they turn out to give the same output. Beware!
if cfg!(target_arch = "x86") || cfg!(target_arch = "x86_64") {
fuzz_based_test(&input, config, &crc32);
} else {
fuzz_based_test(&input, config, &other);
}
}
HashCalcVariant::Standard | HashCalcVariant::Roll => {
fuzz_based_test(&input, config, &other);
}
}
fuzz_based_test(&input, config, &expected);
}

#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
Expand All @@ -4243,5 +4213,4 @@ mod test {
// TODO: determine whether changing the aligment of this field will improve performance.
const _: () = assert!(offset_of!(State, strstart) == 2824);
}

}
8 changes: 2 additions & 6 deletions zlib-rs/src/deflate/algorithm/medium.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,12 +229,8 @@ fn insert_match(state: &mut State, mut m: Match) {
return;
}

/* Insert new strings in the hash table only if the match length
* is not too large. This saves time but degrades compression.
*/
if (m.match_length as usize) <= 16 * state.max_insert_length()
&& state.lookahead >= WANT_MIN_MATCH
{
// Insert new strings in the hash table
if state.lookahead >= WANT_MIN_MATCH {
m.match_length -= 1; /* string at strstart already in table */
m.strstart += 1;

Expand Down
Loading
Loading