summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Tests/LibCompress/TestXz.cpp58
-rw-r--r--Userland/Libraries/LibCompress/Lzma.cpp2
2 files changed, 59 insertions, 1 deletions
diff --git a/Tests/LibCompress/TestXz.cpp b/Tests/LibCompress/TestXz.cpp
index 73db7532cb..b5f092a1fa 100644
--- a/Tests/LibCompress/TestXz.cpp
+++ b/Tests/LibCompress/TestXz.cpp
@@ -120,6 +120,64 @@ TEST_CASE(lzma2_uncompressed_size_overflow)
EXPECT(buffer_or_error.is_error());
}
+TEST_CASE(lzma2_literal_context_bits_after_state_reset)
+{
+ Array<u8, 72> const compressed {
+ // Stream Header
+ 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, // Magic
+ 0x00, 0x00, // Stream Flags (Check: None)
+ 0xFF, 0x12, 0xD9, 0x41, // CRC32
+
+ // Block Header
+ 0x02, // Block Header Size [(0x02 + 1) * 4, i.e. 12 bytes]
+ 0x00, // Block Flags (one filter, no compressed or uncompressed size present)
+ // Filter 0 Flags
+ 0x21, // Filter ID (0x21 for LZMA2, encoded as a multibyte integer)
+ 0x01, // Size of Properties (0x01, encoded as a multibyte integer)
+ 0x00, // Filter Properties (LZMA2 encoded dictionary size byte; 0x00 = 4 KiB)
+ 0x00, 0x00, 0x00, // Header Padding
+ 0x37, 0x27, 0x97, 0xD6, // CRC32
+
+ // Compressed Data (LZMA2)
+ // LZMA chunk with dictionary reset
+ 0xE0, // Control Byte
+ 0x00, 0x00, // Low 16 bits of uncompressed size minus one (big-endian)
+ 0x00, 0x05, // Compressed size minus one (big-endian)
+ 0x01, // LZMA properties byte (lc = 1; lp = 0; pb = 0)
+ 0x00, 0x3F, 0xFF, 0xFC, 0x00, 0x00,
+ // LZMA chunk with state reset
+ 0xA0, // Control Byte
+ 0x00, 0x01, // Low 16 bits of uncompressed size minus one (big-endian)
+ 0x00, 0x06, // Compressed size minus one (big-endian)
+ 0x00, 0x40, 0x1F, 0xF4, 0x00, 0x00, 0x00,
+ // End of LZMA2 stream
+ 0x00,
+
+ // Block Padding
+ 0x00, 0x00, 0x00,
+
+ // Index
+ 0x00, // Index Indicator
+ 0x01, // Number of Records (multibyte integer)
+ // Record 0
+ 0x25, // Unpadded Size (multibyte integer)
+ 0x03, // Uncompressed Size (multibyte integer)
+ // CRC32
+ 0x76, 0x34, 0x7C, 0x51,
+
+ // Stream Footer
+ 0x06, 0x72, 0x9E, 0x7A, // CRC32
+ 0x01, 0x00, 0x00, 0x00, // Backward Size
+ 0x00, 0x00, // Stream Flags
+ 0x59, 0x5A, // Footer Magic Bytes
+ };
+
+ auto stream = MUST(try_make<FixedMemoryStream>(compressed));
+ auto decompressor = MUST(Compress::XzDecompressor::create(move(stream)));
+ auto buffer = MUST(decompressor->read_until_eof(PAGE_SIZE));
+ EXPECT_EQ("\x80\x80\x80"sv.bytes(), buffer.span());
+}
+
// The following tests are based on test files from the XZ utils package, which have been placed in the public domain:
// https://tukaani.org/xz/xz-5.4.1.tar.xz (subdirectory /xz-5.4.1/tests/files)
// Test descriptions have been taken from the README file in the test files directory.
diff --git a/Userland/Libraries/LibCompress/Lzma.cpp b/Userland/Libraries/LibCompress/Lzma.cpp
index 43a73ffd71..0ff8a38339 100644
--- a/Userland/Libraries/LibCompress/Lzma.cpp
+++ b/Userland/Libraries/LibCompress/Lzma.cpp
@@ -295,7 +295,7 @@ ErrorOr<u16> LzmaDecompressor::decode_symbol_using_reverse_bit_tree(size_t bit_c
ErrorOr<void> LzmaDecompressor::decode_literal_to_output_buffer()
{
u8 previous_byte = 0;
- if (m_total_decoded_bytes > 0) {
+ if (m_dictionary->seekback_limit() > 0) {
auto read_bytes = MUST(m_dictionary->read_with_seekback({ &previous_byte, sizeof(previous_byte) }, 1));
VERIFY(read_bytes.size() == sizeof(previous_byte));
}