From 8533cceed5885573871007073220b33d62fd3e55 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Tue, 16 Mar 2021 20:25:58 +0200 Subject: [PATCH] LibCompress: Fail gracefuly on missing huffman codes in DeflateDecompressor --- Userland/Libraries/LibCompress/Deflate.cpp | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/Userland/Libraries/LibCompress/Deflate.cpp b/Userland/Libraries/LibCompress/Deflate.cpp index 5963aa709a..951da353ed 100644 --- a/Userland/Libraries/LibCompress/Deflate.cpp +++ b/Userland/Libraries/LibCompress/Deflate.cpp @@ -120,7 +120,8 @@ u32 CanonicalCode::read_symbol(InputBitStream& stream) const for (;;) { code_bits = code_bits << 1 | stream.read_bits(1); - VERIFY(code_bits < (1 << 16)); + if (code_bits >= (1 << 16)) + return UINT32_MAX; // the maximum symbol in deflate is 288, so we use UINT32_MAX (an impossible value) to indicate an error // FIXME: This is very inefficient and could greatly be improved by implementing this // algorithm: https://www.hanshq.net/zip.html#huffdec @@ -149,6 +150,11 @@ bool DeflateDecompressor::CompressedBlock::try_read_more() const auto symbol = m_literal_codes.read_symbol(m_decompressor.m_input_stream); + if (symbol == UINT32_MAX) { + m_decompressor.set_fatal_error(); + return false; + } + if (symbol < 256) { m_decompressor.m_output_stream << static_cast(symbol); return true; @@ -162,7 +168,12 @@ bool DeflateDecompressor::CompressedBlock::try_read_more() } const auto length = m_decompressor.decode_length(symbol); - const auto distance = m_decompressor.decode_distance(m_distance_codes.value().read_symbol(m_decompressor.m_input_stream)); + const auto distance_symbol = m_distance_codes.value().read_symbol(m_decompressor.m_input_stream); + if (distance_symbol == UINT32_MAX) { + m_decompressor.set_fatal_error(); + return false; + } + const auto distance = m_decompressor.decode_distance(distance_symbol); for (size_t idx = 0; idx < length; ++idx) { u8 byte = 0; @@ -433,6 +444,11 @@ void DeflateDecompressor::decode_codes(CanonicalCode& literal_code, Optional(symbol)); continue;