diff --git a/Userland/Libraries/LibCompress/Deflate.cpp b/Userland/Libraries/LibCompress/Deflate.cpp index ae8b9ac2bb..bfdeb991a4 100644 --- a/Userland/Libraries/LibCompress/Deflate.cpp +++ b/Userland/Libraries/LibCompress/Deflate.cpp @@ -199,11 +199,17 @@ ErrorOr DeflateDecompressor::CompressedBlock::try_read_more() auto const distance = TRY(m_decompressor.decode_distance(distance_symbol)); - for (size_t idx = 0; idx < length; ++idx) { - u8 byte = 0; - TRY(m_decompressor.m_output_buffer.read_with_seekback({ &byte, sizeof(byte) }, distance)); + if (distance < length) { + for (size_t idx = 0; idx < length; ++idx) { + u8 byte = 0; + TRY(m_decompressor.m_output_buffer.read_with_seekback({ &byte, sizeof(byte) }, distance)); - m_decompressor.m_output_buffer.write({ &byte, sizeof(byte) }); + m_decompressor.m_output_buffer.write({ &byte, sizeof(byte) }); + } + } else { + Array buffer; + auto bytes = TRY(m_decompressor.m_output_buffer.read_with_seekback({ buffer.data(), length }, distance)); + m_decompressor.m_output_buffer.write(bytes); } return true; @@ -386,7 +392,7 @@ ErrorOr DeflateDecompressor::decode_length(u32 symbol) } if (symbol == 285) - return 258; + return DeflateDecompressor::max_back_reference_length; VERIFY_NOT_REACHED(); } diff --git a/Userland/Libraries/LibCompress/Deflate.h b/Userland/Libraries/LibCompress/Deflate.h index 4767032061..1ca761ad40 100644 --- a/Userland/Libraries/LibCompress/Deflate.h +++ b/Userland/Libraries/LibCompress/Deflate.h @@ -104,6 +104,8 @@ private: ErrorOr decode_distance(u32); ErrorOr decode_codes(CanonicalCode& literal_code, Optional& distance_code); + static constexpr u16 max_back_reference_length = 258; + bool m_read_final_bock { false }; State m_state { State::Idle };