diff --git a/Libraries/LibCompress/Deflate.cpp b/Libraries/LibCompress/Deflate.cpp index e827bdffe84..a7f7757d665 100644 --- a/Libraries/LibCompress/Deflate.cpp +++ b/Libraries/LibCompress/Deflate.cpp @@ -136,13 +136,18 @@ bool DeflateDecompressor::CompressedBlock::try_read_more() m_eof = true; return false; } else { + // FIXME: This assertion depends on user input. ASSERT(m_distance_codes.has_value()); const auto run_length = m_decompressor.decode_run_length(symbol); const auto distance = m_decompressor.decode_distance(m_distance_codes.value().read_symbol(m_decompressor.m_input_stream)); - auto bytes = m_decompressor.m_output_stream.reserve_contigous_space(run_length); - m_decompressor.m_output_stream.read(bytes, distance + bytes.size()); + size_t nread = 0; + while (nread < run_length) { + const auto nreserved = min(run_length - nread, m_decompressor.m_output_stream.remaining_contigous_space()); + auto bytes = m_decompressor.m_output_stream.reserve_contigous_space(nreserved); + nread += m_decompressor.m_output_stream.read(bytes, distance + nread + nreserved); + } return true; } diff --git a/Userland/test-compress.cpp b/Userland/test-compress.cpp index bf674fc4fda..321c97bc805 100644 --- a/Userland/test-compress.cpp +++ b/Userland/test-compress.cpp @@ -87,9 +87,6 @@ TEST_CASE(deflate_decompress_multiple_blocks) EXPECT(compare({ uncompressed, sizeof(uncompressed) - 1 }, decompressed.bytes())); } -// FIXME: The following test uses a dynamic encoding which isn't supported by DeflateDecompressor yet. - -/* TEST_CASE(deflate_decompress_zeroes) { const u8 compressed[] = { @@ -103,7 +100,6 @@ TEST_CASE(deflate_decompress_zeroes) const auto decompressed = Compress::DeflateDecompressor::decompress_all({ compressed, sizeof(compressed) }); EXPECT(compare({ uncompressed, sizeof(uncompressed) }, decompressed.bytes())); } -*/ TEST_CASE(zlib_decompress_simple) { @@ -135,7 +131,7 @@ TEST_CASE(gzip_decompress_simple) EXPECT(compare({ uncompressed, sizeof(uncompressed) - 1 }, decompressed.bytes())); } -TEST_CASE(gzip_multiple_members) +TEST_CASE(gzip_decompress_multiple_members) { const u8 compressed[] = { @@ -153,4 +149,30 @@ TEST_CASE(gzip_multiple_members) EXPECT(compare({ uncompressed, sizeof(uncompressed) - 1 }, decompressed.bytes())); } +TEST_CASE(gzip_decompress_zeroes) +{ + const u8 compressed[] = { + 0x1f, 0x8b, 0x08, 0x00, 0x6e, 0x7a, 0x4b, 0x5f, 0x02, 0xff, 0xed, 0xc1, + 0x31, 0x01, 0x00, 0x00, 0x00, 0xc2, 0xa0, 0xf5, 0x4f, 0xed, 0x61, 0x0d, + 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6e, 0xcd, 0xcd, 0xe8, + 0x7e, 0x00, 0x00, 0x02, 0x00 + }; + + const u8 uncompressed[128 * 1024] = { 0 }; + + const auto decompressed = Compress::GzipDecompressor::decompress_all({ compressed, sizeof(compressed) }); + + EXPECT(compare({ uncompressed, sizeof(uncompressed) }, decompressed.bytes())); +} + TEST_MAIN(Compress)