summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIdan Horowitz <idan.horowitz@gmail.com>2021-03-16 20:25:58 +0200
committerAndreas Kling <kling@serenityos.org>2021-03-16 21:57:44 +0100
commit8533cceed5885573871007073220b33d62fd3e55 (patch)
treeab4170dc6e726e11c738b32b56d675ddc3af2af6
parentbe5a8d9c7fa800b4f53d5a2bf0a871f0af42f35f (diff)
downloadserenity-8533cceed5885573871007073220b33d62fd3e55.zip
LibCompress: Fail gracefuly on missing huffman codes in DeflateDecompressor
-rw-r--r--Userland/Libraries/LibCompress/Deflate.cpp20
1 files 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<u8>(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<Can
while (code_lengths.size() < literal_code_count + distance_code_count) {
auto symbol = code_length_code.read_symbol(m_input_stream);
+ if (symbol == UINT32_MAX) {
+ set_fatal_error();
+ return;
+ }
+
if (symbol < DeflateSpecialCodeLengths::COPY) {
code_lengths.append(static_cast<u8>(symbol));
continue;