diff --git a/miniz_oxide/src/inflate/core.rs b/miniz_oxide/src/inflate/core.rs index b78b5313..a6eb6d54 100644 --- a/miniz_oxide/src/inflate/core.rs +++ b/miniz_oxide/src/inflate/core.rs @@ -547,6 +547,10 @@ where code_len = res.1 as u32; }; + if code_len == 0 { + return Action::Jump(InvalidCodeLen); + } + l.bit_buf >>= code_len as u32; l.num_bits -= code_len; f(r, l, symbol) @@ -1077,6 +1081,7 @@ fn decompress_inner( dist_from_out_buf_start: r.dist_from_out_buf_start, }; + let mut status = 'state_machine: loop { match state { Start => { diff --git a/miniz_oxide/tests/test.rs b/miniz_oxide/tests/test.rs index 5cd5796e..6d9f5d5c 100644 --- a/miniz_oxide/tests/test.rs +++ b/miniz_oxide/tests/test.rs @@ -31,8 +31,18 @@ fn inf_issue_19() { let _ = decompress_to_vec(data.as_slice()); } +/// Fuzzed (invalid )file that resulted in an infinite loop as inflate read a code as having 0 +/// length. #[test] -fn decompress_oom() { +fn decompress_zero_code_len_oom() { + let data = get_test_file_data("tests/test_data/invalid_code_len_oom"); + let _ = decompress_to_vec(data.as_slice()); +} + +/// Same problem as previous test but in the end of input huffman decode part of +/// `decode_huffman_code` +#[test] +fn decompress_zero_code_len_2() { let data = get_test_file_data("tests/test_data/invalid_code_len_oom"); let _ = decompress_to_vec(data.as_slice()); } diff --git a/miniz_oxide/tests/test_data/invalid_code_len_short b/miniz_oxide/tests/test_data/invalid_code_len_short new file mode 100644 index 00000000..5ec953d0 Binary files /dev/null and b/miniz_oxide/tests/test_data/invalid_code_len_short differ