diff --git a/miniz_oxide/src/inflate/mod.rs b/miniz_oxide/src/inflate/mod.rs index 53539232..03b9dc98 100644 --- a/miniz_oxide/src/inflate/mod.rs +++ b/miniz_oxide/src/inflate/mod.rs @@ -151,14 +151,12 @@ fn decompress_to_vec_inner( } TINFLStatus::HasMoreOutput => { - // We need more space, so check if we can resize the buffer and do it. - let new_len = ret - .len() - .checked_add(out_pos) - .ok_or(TINFLStatus::HasMoreOutput)?; - if new_len > max_output_size { + // if the buffer has already reached the size limit, return an error + if ret.len() >= max_output_size { return Err(TINFLStatus::HasMoreOutput); - }; + } + // calculate the new length, capped at `max_output_size` + let new_len = ret.len().saturating_mul(2).min(max_output_size); ret.resize(new_len, 0); } diff --git a/miniz_oxide/tests/test.rs b/miniz_oxide/tests/test.rs index 56b12387..388d5d8e 100644 --- a/miniz_oxide/tests/test.rs +++ b/miniz_oxide/tests/test.rs @@ -160,6 +160,25 @@ fn issue_75_empty_input_infinite_loop() { assert!(&d == &[0]); } +#[test] +fn issue_119_inflate_with_exact_limit() { + use miniz_oxide::inflate::{decompress_to_vec_zlib, decompress_to_vec_zlib_with_limit}; + + let compressed_data = [ + 120, 156, 237, 217, 65, 17, 194, 0, 16, 192, 192, 122, 193, 94, 13, 240, 232, 128, 12, 28, 160, 2, 53, 53, 130, 139, 220, 227, 118, 21, 228, 159, 227, 13, 0, 212, 126, 211, 1, 0, 176, 208, 99, 58, 0, 0, 22, 122, 78, 7, 0, 192, 66, 223, 233, 0, 0, 88, 200, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, + 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, + 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 247, 116, 0, 0, 44, 116, 78, 7, 0, 192, 66, 215, 116, 0, 0, 44, 244, 154, 14, 0, 128, 133, 62, 211, 1, 0, 176, 144, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, + 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 252, 95, 0, 232, 249, 191, 0, 208, 243, 127, 1, 160, 231, 255, 2, 64, 207, 255, 5, 128, 158, 255, 11, 0, 61, 255, 23, 0, 122, 254, 47, 0, 244, 254, 53, 209, 27, 197 + ].as_slice(); + + let decompressed_size = decompress_to_vec_zlib(compressed_data) + .expect("test is not valid, data must correctly decompress when not limited") + .len(); + + let _ = decompress_to_vec_zlib_with_limit(compressed_data, decompressed_size) + .expect(format!("data decompression failed when limited to {}", decompressed_size).as_str()); +} + /* #[test] fn large_file() {