From 5adf4901dfc0f504816f03cecf64e21a96562aa1 Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Sat, 25 Apr 2020 17:30:09 +0100 Subject: [PATCH] LibGfx: Fix crash on decoding small gifs The LZW decode step will now copy and pad LZW data out to 4 bytes if there are less than 4 bytes remaining in the buffer. This means it will now also work when the total size of the LZW image data is less than 4 bytes. --- Libraries/LibGfx/GIFLoader.cpp | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Libraries/LibGfx/GIFLoader.cpp b/Libraries/LibGfx/GIFLoader.cpp index ad5c0ae42a..df792891dc 100644 --- a/Libraries/LibGfx/GIFLoader.cpp +++ b/Libraries/LibGfx/GIFLoader.cpp @@ -169,19 +169,19 @@ public: u8 current_bit_offset = m_current_bit_index % 8; u32 mask = (u32)(pow(2, m_code_size) - 1) << current_bit_offset; - // Make sure that we don't read bytes past the end of the data. - int bytes_past_end = current_byte_index + sizeof(mask) - m_lzw_bytes.size(); - u8 bits_past_end = 0; - if (bytes_past_end > 0) { - current_byte_index -= bytes_past_end; - mask <<= bytes_past_end * 8; - bits_past_end = bytes_past_end * 8; + // Make a padded copy of the final bytes in the data to ensure we don't read past the end. + if (current_byte_index + sizeof(mask) > m_lzw_bytes.size()) { + u8 padded_last_bytes[sizeof(mask)] = { 0 }; + for (int i = 0; current_byte_index + i < m_lzw_bytes.size(); ++i) { + padded_last_bytes[i] = m_lzw_bytes[current_byte_index + i]; + } + const u32* addr = (const u32*)&padded_last_bytes; + m_current_code = (*addr & mask) >> current_bit_offset; + } else { + const u32* addr = (const u32*)&m_lzw_bytes.at(current_byte_index); + m_current_code = (*addr & mask) >> current_bit_offset; } - ASSERT(current_byte_index + sizeof(mask) - 1 < m_lzw_bytes.size()); - const u32* addr = (const u32*)&m_lzw_bytes.at(current_byte_index); - m_current_code = (*addr & mask) >> (current_bit_offset + bits_past_end); - if (m_current_code > m_code_table.size()) { dbg() << "Corrupted LZW stream, invalid code: " << m_current_code << " at bit index: " << m_current_bit_index << ", code table size: " << m_code_table.size();