mirror of
https://github.com/RGBCube/serenity
synced 2025-07-27 07:37:46 +00:00
LibCompress: Fail gracefuly on missing huffman codes in DeflateDecompressor
This commit is contained in:
parent
be5a8d9c7f
commit
8533cceed5
1 changed files with 18 additions and 2 deletions
|
@ -120,7 +120,8 @@ u32 CanonicalCode::read_symbol(InputBitStream& stream) const
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
code_bits = code_bits << 1 | stream.read_bits(1);
|
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
|
// FIXME: This is very inefficient and could greatly be improved by implementing this
|
||||||
// algorithm: https://www.hanshq.net/zip.html#huffdec
|
// 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);
|
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) {
|
if (symbol < 256) {
|
||||||
m_decompressor.m_output_stream << static_cast<u8>(symbol);
|
m_decompressor.m_output_stream << static_cast<u8>(symbol);
|
||||||
return true;
|
return true;
|
||||||
|
@ -162,7 +168,12 @@ bool DeflateDecompressor::CompressedBlock::try_read_more()
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto length = m_decompressor.decode_length(symbol);
|
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) {
|
for (size_t idx = 0; idx < length; ++idx) {
|
||||||
u8 byte = 0;
|
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) {
|
while (code_lengths.size() < literal_code_count + distance_code_count) {
|
||||||
auto symbol = code_length_code.read_symbol(m_input_stream);
|
auto symbol = code_length_code.read_symbol(m_input_stream);
|
||||||
|
|
||||||
|
if (symbol == UINT32_MAX) {
|
||||||
|
set_fatal_error();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (symbol < DeflateSpecialCodeLengths::COPY) {
|
if (symbol < DeflateSpecialCodeLengths::COPY) {
|
||||||
code_lengths.append(static_cast<u8>(symbol));
|
code_lengths.append(static_cast<u8>(symbol));
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue