diff --git a/Userland/Libraries/LibCompress/Zlib.cpp b/Userland/Libraries/LibCompress/Zlib.cpp index 852e829935..e3261283a5 100644 --- a/Userland/Libraries/LibCompress/Zlib.cpp +++ b/Userland/Libraries/LibCompress/Zlib.cpp @@ -24,7 +24,6 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include #include #include #include @@ -33,26 +32,38 @@ namespace Compress { -Zlib::Zlib(ReadonlyBytes data) +Optional Zlib::try_create(ReadonlyBytes data) { - m_input_data = data; + if (data.size() < 6) + return {}; // header + footer size is 6 + + Zlib zlib { data }; u8 compression_info = data.at(0); u8 flags = data.at(1); - m_compression_method = compression_info & 0xF; - m_compression_info = (compression_info >> 4) & 0xF; - m_check_bits = flags & 0xF; - m_has_dictionary = (flags >> 5) & 0x1; - m_compression_level = (flags >> 6) & 0x3; - m_checksum = 0; + zlib.m_compression_method = compression_info & 0xF; + zlib.m_compression_info = (compression_info >> 4) & 0xF; + zlib.m_check_bits = flags & 0xF; + zlib.m_has_dictionary = (flags >> 5) & 0x1; + zlib.m_compression_level = (flags >> 6) & 0x3; - VERIFY(m_compression_method == 8); - VERIFY(m_compression_info == 7); - VERIFY(!m_has_dictionary); - VERIFY((compression_info * 256 + flags) % 31 == 0); + if (zlib.m_compression_method != 8 || zlib.m_compression_info > 7) + return {}; // non-deflate compression - m_data_bytes = data.slice(2, data.size() - 2 - 4); + if (zlib.m_has_dictionary) + return {}; // we dont support pre-defined dictionaries + + if ((compression_info * 256 + flags) % 31 != 0) + return {}; // error correction code doesnt match + + zlib.m_data_bytes = data.slice(2, data.size() - 2 - 4); + return zlib; +} + +Zlib::Zlib(const ReadonlyBytes& data) + : m_input_data(data) +{ } Optional Zlib::decompress() @@ -62,8 +73,10 @@ Optional Zlib::decompress() Optional Zlib::decompress_all(ReadonlyBytes bytes) { - Zlib zlib { bytes }; - return zlib.decompress(); + auto zlib = try_create(bytes); + if (!zlib.has_value()) + return {}; + return zlib->decompress(); } u32 Zlib::checksum() diff --git a/Userland/Libraries/LibCompress/Zlib.h b/Userland/Libraries/LibCompress/Zlib.h index aa2a912095..3acafe4bc3 100644 --- a/Userland/Libraries/LibCompress/Zlib.h +++ b/Userland/Libraries/LibCompress/Zlib.h @@ -34,21 +34,22 @@ namespace Compress { class Zlib { public: - Zlib(ReadonlyBytes data); - Optional decompress(); u32 checksum(); + static Optional try_create(ReadonlyBytes data); static Optional decompress_all(ReadonlyBytes); private: + Zlib(const ReadonlyBytes& data); + u8 m_compression_method; u8 m_compression_info; u8 m_check_bits; u8 m_has_dictionary; u8 m_compression_level; - u32 m_checksum; + u32 m_checksum { 0 }; ReadonlyBytes m_input_data; ReadonlyBytes m_data_bytes; };