diff --git a/Tests/LibCompress/CMakeLists.txt b/Tests/LibCompress/CMakeLists.txt index 691b5553a6..7d15595468 100644 --- a/Tests/LibCompress/CMakeLists.txt +++ b/Tests/LibCompress/CMakeLists.txt @@ -12,3 +12,4 @@ foreach(source IN LISTS TEST_SOURCES) endforeach() install(DIRECTORY brotli-test-files DESTINATION usr/Tests/LibCompress) +install(DIRECTORY deflate-test-files DESTINATION usr/Tests/LibCompress) diff --git a/Tests/LibCompress/TestDeflate.cpp b/Tests/LibCompress/TestDeflate.cpp index da53aefef2..2b5e8fc51f 100644 --- a/Tests/LibCompress/TestDeflate.cpp +++ b/Tests/LibCompress/TestDeflate.cpp @@ -11,8 +11,15 @@ #include #include #include +#include #include +#ifdef AK_OS_SERENITY +# define TEST_INPUT(x) ("/usr/Tests/LibCompress/deflate-test-files/" x) +#else +# define TEST_INPUT(x) ("deflate-test-files/" x) +#endif + TEST_CASE(canonical_code_simple) { Array const code { @@ -155,3 +162,13 @@ TEST_CASE(deflate_compress_literals) Array test { 0, 0, 0, 0, 0x72, 0, 0, 0xee, 0, 0, 0, 0x26, 0, 0, 0, 0x28, 0, 0, 0x72 }; auto compressed = TRY_OR_FAIL(Compress::DeflateCompressor::compress_all(test, Compress::DeflateCompressor::CompressionLevel::GOOD)); } + +TEST_CASE(ossfuzz_63183) +{ + auto path = TEST_INPUT("clusterfuzz-testcase-minimized-FuzzDeflateCompression-6163230961303552.fuzz"sv); + auto test_file = MUST(Core::File::open(path, Core::File::OpenMode::Read)); + auto test_data = MUST(test_file->read_until_eof()); + auto compressed = TRY_OR_FAIL(Compress::DeflateCompressor::compress_all(test_data, Compress::DeflateCompressor::CompressionLevel::GOOD)); + auto decompressed = TRY_OR_FAIL(Compress::DeflateDecompressor::decompress_all(compressed)); + EXPECT(test_data == decompressed); +} diff --git a/Tests/LibCompress/deflate-test-files/clusterfuzz-testcase-minimized-FuzzDeflateCompression-6163230961303552.fuzz b/Tests/LibCompress/deflate-test-files/clusterfuzz-testcase-minimized-FuzzDeflateCompression-6163230961303552.fuzz new file mode 100644 index 0000000000..91158016c0 Binary files /dev/null and b/Tests/LibCompress/deflate-test-files/clusterfuzz-testcase-minimized-FuzzDeflateCompression-6163230961303552.fuzz differ diff --git a/Userland/Libraries/LibCompress/Deflate.cpp b/Userland/Libraries/LibCompress/Deflate.cpp index 18216fb124..457701c81e 100644 --- a/Userland/Libraries/LibCompress/Deflate.cpp +++ b/Userland/Libraries/LibCompress/Deflate.cpp @@ -625,7 +625,7 @@ void DeflateCompressor::generate_huffman_lengths(Array& lengths, Array u16 heap_keys[Size]; // Used for O(n) heap construction u16 heap_values[Size]; - u16 huffman_links[Size * 2 + 1] = { 0 }; + u16 huffman_links[Size * 2] = { 0 }; size_t non_zero_freqs = 0; for (size_t i = 0; i < Size; i++) { auto frequency = frequencies[i]; @@ -657,7 +657,7 @@ void DeflateCompressor::generate_huffman_lengths(Array& lengths, Array u16 second_lowest_frequency = heap.peek_min_key(); u16 second_lowest_link = heap.pop_min(); - u16 new_link = heap.size() + 2; + u16 new_link = heap.size() + 1; heap.insert(lowest_frequency + second_lowest_frequency, new_link); @@ -676,7 +676,7 @@ void DeflateCompressor::generate_huffman_lengths(Array& lengths, Array non_zero_freqs++; size_t bit_length = 1; - while (link != 2) { + while (link != 1) { bit_length++; link = huffman_links[link]; }