/* * Copyright (c) 2023, Tim Schumacher * * SPDX-License-Identifier: BSD-2-Clause */ #include #include #include TEST_CASE(lzma2_compressed_without_settings_after_uncompressed) { Array 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) 0x31, // LZMA properties byte (lc = 1; lp = 1; pb = 1) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Uncompressed chunk without dictionary reset 0x02, // Control Byte 0x00, 0x00, // 16-bit data size minus one (big-endian) 0x00, // LZMA chunk with state reset 0xa0, // Control Byte 0x00, 0x00, // Low 16 bits of uncompressed size minus one (big-endian) 0x00, 0x05, // Compressed size minus one (big-endian) 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // End of LZMA2 stream 0x00, // Index 0x00, // Index Indicator 0x01, // Number of Records (multibyte integer) // Record 0 0x28, // Unpadded Size (multibyte integer) 0x03, // Uncompressed Size (multibyte integer) // CRC32 0x3B, 0x4A, 0xD2, 0xE4, // 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(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ("\x00\x00\x00"sv.bytes(), buffer.span()); } TEST_CASE(lzma2_uncompressed_size_overflow) { Array 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) // Uncompressed chunk with dictionary reset 0x01, // Control Byte 0xFF, 0xFF, // 16-bit data size minus one (big-endian) // Note: The following data should be handled as verbatim data if handled correctly. // If the size overflows, no bytes will be copied and it will be interpreted as the remainder of the XZ stream. // End of LZMA2 stream 0x00, // Index 0x00, // Index Indicator 0x01, // Number of Records (multibyte integer) // Record 0 0x10, // Unpadded Size (multibyte integer) 0x00, // Uncompressed Size (multibyte integer) // CRC32 0x7A, 0xA7, 0x44, 0x6A, // 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(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); // If the size overflows (and the uncompressed size being 0 doesn't get caught otherwise), the data payload will be interpreted as stream metadata, resulting in a valid stream. // If the size doesn't overflow, the stream ends in the middle unexpectedly, which should result in an error. EXPECT(buffer_or_error.is_error()); } TEST_CASE(lzma2_literal_context_bits_after_state_reset) { Array 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(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(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. TEST_CASE(xz_utils_bad_0_backward_size) { // "bad-0-backward_size.xz has wrong Backward Size in Stream Footer." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x35, 0x91, 0xC5, 0xC6, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_0cat_alone) { // "bad-0cat-alone.xz is good-0-empty.xz concatenated with an empty LZMA_Alone file." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A, 0x5D, 0x00, 0x00, 0x01, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x83, 0xFF, 0xFB, 0xFF, 0xFF, 0xC0, 0x00, 0x00, 0x00 }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_0cat_header_magic) { // "bad-0cat-header_magic.xz is good-0cat-empty.xz but with one byte // wrong in the Header Magic Bytes field of the second Stream." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A, 0xFD, 0x37, 0x7A, 0x58, 0x59, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_0catpad_empty) { // "bad-0catpad-empty.xz has two zero-Block Streams concatenated with // five-byte Stream Padding between the Streams." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_0_empty_truncated) { // "bad-0-empty-truncated.xz is good-0-empty.xz without the last byte // of the file." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59 }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_0_footer_magic) { // "bad-0-footer_magic.xz is good-0-empty.xz but with one byte wrong // in the Footer Magic Bytes field." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x58 }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_0_header_magic) { // "bad-0-header_magic.xz is good-0-empty.xz but with one byte wrong // in the Header Magic Bytes field." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x59, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_0_nonempty_index) { // "bad-0-nonempty_index.xz has no Blocks but Index claims that there is // one Block." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x01, 0x00, 0x00, 0x2B, 0xB5, 0x86, 0x20, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_0pad_empty) { // "bad-0pad-empty.xz has one Stream with no Blocks followed by // five-byte Stream Padding. Stream Padding must be a multiple of four // bytes, thus this file is corrupt." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00 }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_block_header_1) { // "bad-1-block_header-1.xz has Block Header that ends in the middle of // the Filter Flags field." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x01, 0x00, 0x21, 0x01, 0x0C, 0x9D, 0x60, 0x62, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_block_header_2) { // "bad-1-block_header-2.xz has Block Header that has Compressed Size and // Uncompressed Size but no List of Filter Flags field." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x01, 0xC0, 0x04, 0x0D, 0x80, 0x97, 0x8A, 0x12, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_block_header_3) { // "bad-1-block_header-3.xz has wrong CRC32 in Block Header." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x33, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_block_header_4) { // "bad-1-block_header-4.xz has too big Compressed Size in Block Header // (2^63 - 1 bytes while maximum is a little less, because the whole // Block must stay smaller than 2^63). It's important that the file // gets rejected due to invalid Compressed Size value; the decoder // must not try decoding the Compressed Data field." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x04, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x21, 0x01, 0x08, 0x00, 0x00, 0x63, 0xE2, 0x3A, 0x70, 0x01, 0x00, 0x0C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x29, 0x0D, 0x7D, 0x56, 0x71, 0x1A, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: The specification apparently doesn't mention that a block has to be smaller than 2^63, investigate. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_bad_1_block_header_5) { // "bad-1-block_header-5.xz has zero as Compressed Size in Block Header." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x03, 0xC0, 0x00, 0x0D, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x34, 0x55, 0x23, 0x01, 0x00, 0x0C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x25, 0x0D, 0x71, 0x19, 0xC4, 0xB6, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_block_header_6) { // "bad-1-block_header-6.xz has corrupt Block Header which may crash // xz -lvv in XZ Utils 5.0.3 and earlier." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0xC0, 0x11, 0x0D, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xDE, 0x39, 0xEB, 0x01, 0x00, 0x0C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x25, 0x0D, 0x71, 0x19, 0xC4, 0xB6, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_check_crc32) { // "bad-1-check-crc32.xz has wrong Check (CRC32)." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x14, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: We currently don't check the uncompressed data against the check value. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_bad_1_check_crc32_2) { // "bad-1-check-crc32-2.xz has Compressed Size and Uncompressed Size in // Block Header but wrong Check (CRC32) in the actual data." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x03, 0xC0, 0x11, 0x0D, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0xDE, 0x39, 0xEB, 0x01, 0x00, 0x0C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA3, 0xA2, 0xFF, 0x00, 0x01, 0x25, 0x0D, 0x71, 0x19, 0xC4, 0xB6, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: We currently don't check the uncompressed data against the check value. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_bad_1_check_crc64) { // "bad-1-check-crc64.xz has wrong Check (CRC64)." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x04, 0xE6, 0xD6, 0xB4, 0x46, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0xEF, 0x2E, 0x88, 0x11, 0x9D, 0x3F, 0x96, 0xCB, 0x00, 0x01, 0x28, 0x0D, 0x3C, 0x67, 0x6A, 0x03, 0x1F, 0xB6, 0xF3, 0x7D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: We currently don't check the uncompressed data against the check value. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_bad_1_check_sha256) { // "bad-1-check-sha256.xz has wrong Check (SHA-256)." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x0A, 0xE1, 0xFB, 0x0C, 0xA1, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x8E, 0x59, 0x35, 0xE7, 0xE1, 0x33, 0x68, 0xCD, 0x96, 0x88, 0xFE, 0x8F, 0x48, 0xA0, 0x95, 0x52, 0x93, 0x67, 0x6A, 0x02, 0x15, 0x62, 0x58, 0x2C, 0x7E, 0x84, 0x8D, 0xAF, 0xE1, 0x3F, 0xB0, 0x47, 0x00, 0x01, 0x40, 0x0D, 0x93, 0x86, 0x4E, 0xAE, 0x18, 0x9B, 0x4B, 0x9A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: We currently don't check the uncompressed data against the check value. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_bad_1_lzma2_1) { // "bad-1-lzma2-1.xz has LZMA2 stream whose first chunk (uncompressed) // doesn't reset the dictionary." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x00, 0xFF, 0x12, 0xD9, 0x41, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x02, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0x01, 0x20, 0x0D, 0x34, 0xED, 0xB3, 0xCB, 0x06, 0x72, 0x9E, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_lzma2_2) { // "bad-1-lzma2-2.xz has two LZMA2 chunks, of which the second chunk // indicates dictionary reset, but the LZMA compressed data tries to // repeat data from the previous chunk." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0xE0, 0x00, 0xE2, 0x00, 0xB6, 0x5D, 0x00, 0x26, 0x1B, 0xCA, 0x46, 0x67, 0x5A, 0xF2, 0x77, 0xB8, 0x7D, 0x86, 0xD8, 0x41, 0xDB, 0x05, 0x35, 0xCD, 0x83, 0xA5, 0x7C, 0x12, 0xA5, 0x05, 0xDB, 0x90, 0xBD, 0x2F, 0x14, 0xD3, 0x71, 0x72, 0x96, 0xA8, 0x8A, 0x7D, 0x84, 0x56, 0x71, 0x8D, 0x6A, 0x22, 0x98, 0xAB, 0x9E, 0x3D, 0x90, 0x80, 0x2D, 0xC7, 0x5E, 0x0C, 0x12, 0x52, 0xD3, 0x3F, 0x07, 0x08, 0x7B, 0x1C, 0xA4, 0x77, 0xF3, 0x13, 0xB8, 0x17, 0xC0, 0xEE, 0x91, 0x81, 0x39, 0xB3, 0x87, 0xF0, 0xFF, 0x00, 0xB3, 0x6A, 0x52, 0x41, 0xED, 0x2E, 0xB0, 0xF2, 0x64, 0x97, 0xA4, 0x9A, 0x9E, 0x63, 0xA1, 0xAE, 0x19, 0x74, 0x0D, 0xA9, 0xD5, 0x5B, 0x6C, 0xEE, 0xB1, 0xE0, 0x2C, 0xDC, 0x61, 0xDC, 0xCB, 0x9D, 0x86, 0xCF, 0xE1, 0xDC, 0x0A, 0x7A, 0x81, 0x14, 0x5F, 0xD0, 0x40, 0xC8, 0x7E, 0x0D, 0x97, 0x44, 0xCE, 0xB5, 0xC2, 0xFC, 0x2C, 0x59, 0x08, 0xBF, 0x03, 0x80, 0xDC, 0xD7, 0x44, 0x8E, 0xB3, 0xD4, 0x2D, 0xDE, 0xE5, 0x16, 0x21, 0x6E, 0x47, 0x82, 0xAC, 0x08, 0x59, 0xD8, 0xE4, 0x66, 0x29, 0x61, 0xD5, 0xD1, 0xFA, 0x49, 0x63, 0x90, 0x11, 0x3E, 0x20, 0xD0, 0xA9, 0xE2, 0xD5, 0x14, 0x81, 0xD9, 0x23, 0xD0, 0x8F, 0x43, 0xAE, 0x45, 0x55, 0x36, 0x69, 0xAA, 0x00, 0xE0, 0x00, 0xE5, 0x00, 0xAD, 0x0B, 0x00, 0x8C, 0xF1, 0x9D, 0x40, 0x2B, 0xD0, 0x7D, 0x1D, 0x99, 0xEE, 0xE4, 0xDC, 0x63, 0x74, 0x64, 0x46, 0xA4, 0xA0, 0x4A, 0x64, 0x65, 0xB2, 0xF6, 0x4E, 0xC1, 0xC8, 0x68, 0x9F, 0x27, 0x54, 0xAD, 0xBB, 0xA6, 0x34, 0x3C, 0x77, 0xEC, 0x0F, 0x2E, 0x1B, 0x8E, 0x42, 0x27, 0xE5, 0x68, 0xBF, 0x60, 0xF4, 0x0B, 0x3A, 0xF0, 0x9B, 0x31, 0xEB, 0xDF, 0x3F, 0xD8, 0xAF, 0xA5, 0x55, 0x92, 0x46, 0x05, 0x58, 0x22, 0x09, 0x8F, 0xA8, 0x60, 0x08, 0x0B, 0xA3, 0xE9, 0x3E, 0xBC, 0xB4, 0x16, 0xDB, 0xC7, 0xA3, 0xA2, 0xC0, 0x16, 0xD5, 0x14, 0xA7, 0x22, 0xE8, 0x2F, 0xE8, 0xB4, 0xD0, 0x77, 0x17, 0xC5, 0x8B, 0xE4, 0xF2, 0xBB, 0x6B, 0xD6, 0xEF, 0x9A, 0x81, 0x34, 0x4E, 0x1D, 0xDC, 0xEC, 0x36, 0xE6, 0x44, 0x72, 0xBF, 0x29, 0xB5, 0x3C, 0x05, 0x31, 0x60, 0x66, 0xBA, 0x2C, 0x03, 0x0F, 0xD6, 0x47, 0xC6, 0x7D, 0x85, 0xD4, 0xC5, 0x5E, 0x4E, 0x57, 0x73, 0xC3, 0x41, 0x69, 0xBE, 0x0D, 0x8C, 0x9C, 0xB5, 0x15, 0xA9, 0xE7, 0xD2, 0x78, 0x51, 0x4B, 0xD5, 0x29, 0xD0, 0xF9, 0x35, 0x1A, 0xC5, 0x5D, 0xF4, 0x8C, 0x7A, 0x70, 0xD5, 0x5E, 0xA8, 0x31, 0x57, 0x80, 0xC8, 0xA5, 0xD8, 0xE0, 0x00, 0x00, 0x00, 0xFB, 0x47, 0x48, 0xDB, 0x00, 0x01, 0x82, 0x03, 0xC9, 0x03, 0x00, 0x00, 0x0B, 0x04, 0x8E, 0xDE, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_lzma2_3) { // "bad-1-lzma2-3.xz sets new invalid properties (lc=8, lp=0, pb=0) in // the middle of Block." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0xE0, 0x00, 0xE2, 0x00, 0xB6, 0x5D, 0x00, 0x26, 0x1B, 0xCA, 0x46, 0x67, 0x5A, 0xF2, 0x77, 0xB8, 0x7D, 0x86, 0xD8, 0x41, 0xDB, 0x05, 0x35, 0xCD, 0x83, 0xA5, 0x7C, 0x12, 0xA5, 0x05, 0xDB, 0x90, 0xBD, 0x2F, 0x14, 0xD3, 0x71, 0x72, 0x96, 0xA8, 0x8A, 0x7D, 0x84, 0x56, 0x71, 0x8D, 0x6A, 0x22, 0x98, 0xAB, 0x9E, 0x3D, 0x90, 0x80, 0x2D, 0xC7, 0x5E, 0x0C, 0x12, 0x52, 0xD3, 0x3F, 0x07, 0x08, 0x7B, 0x1C, 0xA4, 0x77, 0xF3, 0x13, 0xB8, 0x17, 0xC0, 0xEE, 0x91, 0x81, 0x39, 0xB3, 0x87, 0xF0, 0xFF, 0x00, 0xB3, 0x6A, 0x52, 0x41, 0xED, 0x2E, 0xB0, 0xF2, 0x64, 0x97, 0xA4, 0x9A, 0x9E, 0x63, 0xA1, 0xAE, 0x19, 0x74, 0x0D, 0xA9, 0xD5, 0x5B, 0x6C, 0xEE, 0xB1, 0xE0, 0x2C, 0xDC, 0x61, 0xDC, 0xCB, 0x9D, 0x86, 0xCF, 0xE1, 0xDC, 0x0A, 0x7A, 0x81, 0x14, 0x5F, 0xD0, 0x40, 0xC8, 0x7E, 0x0D, 0x97, 0x44, 0xCE, 0xB5, 0xC2, 0xFC, 0x2C, 0x59, 0x08, 0xBF, 0x03, 0x80, 0xDC, 0xD7, 0x44, 0x8E, 0xB3, 0xD4, 0x2D, 0xDE, 0xE5, 0x16, 0x21, 0x6E, 0x47, 0x82, 0xAC, 0x08, 0x59, 0xD8, 0xE4, 0x66, 0x29, 0x61, 0xD5, 0xD1, 0xFA, 0x49, 0x63, 0x90, 0x11, 0x3E, 0x20, 0xD0, 0xA9, 0xE2, 0xD5, 0x14, 0x81, 0xD9, 0x23, 0xD0, 0x8F, 0x43, 0xAE, 0x45, 0x55, 0x36, 0x69, 0xAA, 0x00, 0xC0, 0x00, 0xE5, 0x00, 0xAD, 0x08, 0x00, 0x8C, 0xF1, 0x9D, 0x40, 0x2B, 0xD0, 0x7D, 0x1D, 0x99, 0xEE, 0xE4, 0xDC, 0x63, 0x74, 0x64, 0x46, 0xA4, 0xA0, 0x4A, 0x64, 0x65, 0xB2, 0xF6, 0x4E, 0xC1, 0xC8, 0x68, 0x9F, 0x27, 0x54, 0xAD, 0xBB, 0xA6, 0x34, 0x3C, 0x77, 0xEC, 0x0F, 0x2E, 0x1B, 0x8E, 0x42, 0x27, 0xE5, 0x68, 0xBF, 0x60, 0xF4, 0x0B, 0x3A, 0xF0, 0x9B, 0x31, 0xEB, 0xDF, 0x3F, 0xD8, 0xAF, 0xA5, 0x55, 0x92, 0x46, 0x05, 0x58, 0x22, 0x09, 0x8F, 0xA8, 0x60, 0x08, 0x0B, 0xA3, 0xE9, 0x3E, 0xBC, 0xB4, 0x16, 0xDB, 0xC7, 0xA3, 0xA2, 0xC0, 0x16, 0xD5, 0x14, 0xA7, 0x22, 0xE8, 0x2F, 0xE8, 0xB4, 0xD0, 0x77, 0x17, 0xC5, 0x8B, 0xE4, 0xF2, 0xBB, 0x6B, 0xD6, 0xEF, 0x9A, 0x81, 0x34, 0x4E, 0x1D, 0xDC, 0xEC, 0x36, 0xE6, 0x44, 0x72, 0xBF, 0x29, 0xB5, 0x3C, 0x05, 0x31, 0x60, 0x66, 0xBA, 0x2C, 0x03, 0x0F, 0xD6, 0x47, 0xC6, 0x7D, 0x85, 0xD4, 0xC5, 0x5E, 0x4E, 0x57, 0x73, 0xC3, 0x41, 0x69, 0xBE, 0x0D, 0x8C, 0x9C, 0xB5, 0x15, 0xA9, 0xE7, 0xD2, 0x78, 0x51, 0x4B, 0xD5, 0x29, 0xD0, 0xF9, 0x35, 0x1A, 0xC5, 0x5D, 0xF4, 0x8C, 0x7A, 0x70, 0xD5, 0x5E, 0xA8, 0x31, 0x57, 0x80, 0xC8, 0xA5, 0xD8, 0xE0, 0x00, 0x00, 0x00, 0xFB, 0x47, 0x48, 0xDB, 0x00, 0x01, 0x82, 0x03, 0xC9, 0x03, 0x00, 0x00, 0x0B, 0x04, 0x8E, 0xDE, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_lzma2_4) { // "bad-1-lzma2-4.xz has two LZMA2 chunks, of which the first is // uncompressed and the second is LZMA. The first chunk resets dictionary // as it should, but the second chunk tries to reset state without // specifying properties for LZMA." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x34, 0x4C, 0x6F, 0x72, 0x65, 0x6D, 0x20, 0x69, 0x70, 0x73, 0x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x65, 0x63, 0x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, 0x69, 0x63, 0x69, 0x6E, 0x67, 0x20, 0x0A, 0xA0, 0x01, 0x93, 0x01, 0x24, 0x00, 0x32, 0x9B, 0x09, 0x6C, 0x54, 0xD7, 0x2E, 0x95, 0x6C, 0xF9, 0xF7, 0x37, 0xD5, 0x1C, 0xE2, 0x46, 0x02, 0x82, 0x75, 0xFB, 0x49, 0x76, 0x8D, 0x73, 0x53, 0xB6, 0xFD, 0x6D, 0xDB, 0xCA, 0xDB, 0xD9, 0x44, 0x0B, 0xB1, 0x2E, 0xBE, 0x13, 0xB6, 0xBA, 0xA8, 0xE2, 0xF3, 0xED, 0x75, 0x54, 0xDC, 0x41, 0x20, 0xCC, 0xBF, 0x36, 0x5B, 0x20, 0x99, 0x5D, 0x0F, 0x21, 0xA1, 0x06, 0xA3, 0x96, 0x2D, 0xB7, 0x97, 0x9C, 0xF0, 0x7B, 0xFE, 0xE2, 0x12, 0x8C, 0x2D, 0x51, 0xF0, 0xDB, 0x76, 0x77, 0x7D, 0xA4, 0x7B, 0xD3, 0x95, 0xE9, 0xFB, 0x05, 0xE6, 0xF5, 0x97, 0x8F, 0x62, 0xE9, 0xDB, 0x30, 0xBB, 0xB4, 0x70, 0x3D, 0x16, 0x78, 0x03, 0x77, 0x3A, 0x8B, 0x7A, 0xD5, 0xB8, 0xF8, 0x4A, 0x27, 0x25, 0xF5, 0x8E, 0xAA, 0x24, 0x14, 0xA6, 0x29, 0x28, 0x6B, 0x2F, 0x73, 0xE0, 0xA1, 0x71, 0xB4, 0x7B, 0xA4, 0x80, 0x50, 0x40, 0xCA, 0xEF, 0xDB, 0xB4, 0x95, 0xFD, 0xBB, 0xC1, 0x8C, 0x8E, 0x60, 0x97, 0xDB, 0xCB, 0x7F, 0x21, 0xED, 0xC0, 0x10, 0x71, 0x1A, 0x7D, 0xCB, 0xCD, 0x09, 0xD0, 0xD9, 0xFF, 0x6D, 0x80, 0xC0, 0x67, 0x7D, 0x3F, 0xC6, 0x94, 0xCF, 0x5B, 0xDD, 0x51, 0x11, 0xD1, 0xCB, 0xD4, 0x20, 0xD7, 0x2B, 0x84, 0x4E, 0xA8, 0x45, 0xBB, 0x42, 0x78, 0x1A, 0x68, 0x40, 0x5F, 0x24, 0x5E, 0x89, 0x3A, 0x36, 0x7D, 0xDB, 0x98, 0x28, 0xCC, 0xF9, 0x83, 0xEC, 0x32, 0x06, 0x31, 0x47, 0x47, 0x3B, 0x6C, 0x1C, 0xF4, 0x62, 0x34, 0x40, 0xB3, 0x28, 0xBB, 0x54, 0x36, 0xDD, 0x7A, 0x0E, 0x1C, 0x36, 0x25, 0x38, 0x58, 0x06, 0xF8, 0x15, 0xA3, 0xCE, 0x18, 0xC8, 0xFD, 0x96, 0x1E, 0x69, 0x29, 0x03, 0xC3, 0xBD, 0x27, 0xF3, 0xE7, 0x8F, 0xDB, 0x73, 0xB4, 0x2B, 0x4F, 0x38, 0x58, 0x24, 0xBF, 0x83, 0x14, 0x39, 0x7E, 0x73, 0xEE, 0xFE, 0xCF, 0xCA, 0xBD, 0xF3, 0x21, 0x6A, 0x28, 0x80, 0xC8, 0x8E, 0x5D, 0x81, 0xC7, 0xBC, 0x17, 0xD0, 0x2C, 0x93, 0xB5, 0x08, 0x95, 0xBA, 0x0E, 0x92, 0x82, 0x66, 0xAE, 0xFF, 0xB8, 0x03, 0x00, 0x00, 0xFB, 0x47, 0x48, 0xDB, 0x00, 0x01, 0xF3, 0x02, 0xC9, 0x03, 0x00, 0x00, 0xDF, 0xF3, 0x90, 0x23, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_lzma2_5) { // "bad-1-lzma2-5.xz is like bad-1-lzma2-4.xz but doesn't try to reset // anything in the header of the second chunk." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x34, 0x4C, 0x6F, 0x72, 0x65, 0x6D, 0x20, 0x69, 0x70, 0x73, 0x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x65, 0x63, 0x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, 0x69, 0x63, 0x69, 0x6E, 0x67, 0x20, 0x0A, 0x80, 0x01, 0x93, 0x01, 0x24, 0x00, 0x32, 0x9B, 0x09, 0x6C, 0x54, 0xD7, 0x2E, 0x95, 0x6C, 0xF9, 0xF7, 0x37, 0xD5, 0x1C, 0xE2, 0x46, 0x02, 0x82, 0x75, 0xFB, 0x49, 0x76, 0x8D, 0x73, 0x53, 0xB6, 0xFD, 0x6D, 0xDB, 0xCA, 0xDB, 0xD9, 0x44, 0x0B, 0xB1, 0x2E, 0xBE, 0x13, 0xB6, 0xBA, 0xA8, 0xE2, 0xF3, 0xED, 0x75, 0x54, 0xDC, 0x41, 0x20, 0xCC, 0xBF, 0x36, 0x5B, 0x20, 0x99, 0x5D, 0x0F, 0x21, 0xA1, 0x06, 0xA3, 0x96, 0x2D, 0xB7, 0x97, 0x9C, 0xF0, 0x7B, 0xFE, 0xE2, 0x12, 0x8C, 0x2D, 0x51, 0xF0, 0xDB, 0x76, 0x77, 0x7D, 0xA4, 0x7B, 0xD3, 0x95, 0xE9, 0xFB, 0x05, 0xE6, 0xF5, 0x97, 0x8F, 0x62, 0xE9, 0xDB, 0x30, 0xBB, 0xB4, 0x70, 0x3D, 0x16, 0x78, 0x03, 0x77, 0x3A, 0x8B, 0x7A, 0xD5, 0xB8, 0xF8, 0x4A, 0x27, 0x25, 0xF5, 0x8E, 0xAA, 0x24, 0x14, 0xA6, 0x29, 0x28, 0x6B, 0x2F, 0x73, 0xE0, 0xA1, 0x71, 0xB4, 0x7B, 0xA4, 0x80, 0x50, 0x40, 0xCA, 0xEF, 0xDB, 0xB4, 0x95, 0xFD, 0xBB, 0xC1, 0x8C, 0x8E, 0x60, 0x97, 0xDB, 0xCB, 0x7F, 0x21, 0xED, 0xC0, 0x10, 0x71, 0x1A, 0x7D, 0xCB, 0xCD, 0x09, 0xD0, 0xD9, 0xFF, 0x6D, 0x80, 0xC0, 0x67, 0x7D, 0x3F, 0xC6, 0x94, 0xCF, 0x5B, 0xDD, 0x51, 0x11, 0xD1, 0xCB, 0xD4, 0x20, 0xD7, 0x2B, 0x84, 0x4E, 0xA8, 0x45, 0xBB, 0x42, 0x78, 0x1A, 0x68, 0x40, 0x5F, 0x24, 0x5E, 0x89, 0x3A, 0x36, 0x7D, 0xDB, 0x98, 0x28, 0xCC, 0xF9, 0x83, 0xEC, 0x32, 0x06, 0x31, 0x47, 0x47, 0x3B, 0x6C, 0x1C, 0xF4, 0x62, 0x34, 0x40, 0xB3, 0x28, 0xBB, 0x54, 0x36, 0xDD, 0x7A, 0x0E, 0x1C, 0x36, 0x25, 0x38, 0x58, 0x06, 0xF8, 0x15, 0xA3, 0xCE, 0x18, 0xC8, 0xFD, 0x96, 0x1E, 0x69, 0x29, 0x03, 0xC3, 0xBD, 0x27, 0xF3, 0xE7, 0x8F, 0xDB, 0x73, 0xB4, 0x2B, 0x4F, 0x38, 0x58, 0x24, 0xBF, 0x83, 0x14, 0x39, 0x7E, 0x73, 0xEE, 0xFE, 0xCF, 0xCA, 0xBD, 0xF3, 0x21, 0x6A, 0x28, 0x80, 0xC8, 0x8E, 0x5D, 0x81, 0xC7, 0xBC, 0x17, 0xD0, 0x2C, 0x93, 0xB5, 0x08, 0x95, 0xBA, 0x0E, 0x92, 0x82, 0x66, 0xAE, 0xFF, 0xB8, 0x03, 0x00, 0x00, 0xFB, 0x47, 0x48, 0xDB, 0x00, 0x01, 0xF3, 0x02, 0xC9, 0x03, 0x00, 0x00, 0xDF, 0xF3, 0x90, 0x23, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_lzma2_6) { // "bad-1-lzma2-6.xz has reserved LZMA2 control byte value (0x03)." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x03, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_lzma2_7) { // "bad-1-lzma2-7.xz has EOPM at LZMA level." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x04, 0xE6, 0xD6, 0xB4, 0x46, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0xE0, 0x01, 0xC8, 0x01, 0x57, 0x5D, 0x00, 0x26, 0x1B, 0xCA, 0x46, 0x67, 0x5A, 0xF2, 0x77, 0xB8, 0x7D, 0x86, 0xD8, 0x41, 0xDB, 0x05, 0x35, 0xCD, 0x83, 0xA5, 0x7C, 0x12, 0xA5, 0x05, 0xDB, 0x90, 0xBD, 0x2F, 0x14, 0xD3, 0x71, 0x12, 0x7C, 0x4D, 0xCD, 0x11, 0xA9, 0xE3, 0x65, 0x01, 0x2E, 0x86, 0x49, 0x86, 0x92, 0x42, 0x32, 0x52, 0x94, 0x2E, 0x10, 0x5F, 0xB7, 0x8E, 0x8F, 0xFD, 0xF5, 0x1B, 0xC6, 0x26, 0x01, 0xF0, 0xB3, 0xBB, 0xBB, 0x6E, 0xC5, 0x7A, 0x96, 0xE1, 0xDF, 0xC8, 0x34, 0xC3, 0xF5, 0x4F, 0x83, 0x06, 0x28, 0x51, 0x81, 0x64, 0xF9, 0x80, 0x6A, 0x71, 0x47, 0xD0, 0xE2, 0xA6, 0xD6, 0x0D, 0x64, 0x31, 0xCF, 0x8A, 0x30, 0x62, 0xFB, 0x73, 0x35, 0x4A, 0x10, 0x05, 0xC4, 0xCE, 0xEF, 0xB4, 0xFE, 0xD3, 0x85, 0x36, 0xE0, 0xE9, 0x67, 0xC0, 0xF0, 0xB5, 0xA1, 0x1E, 0x52, 0x58, 0x54, 0xDD, 0x40, 0x56, 0xF8, 0x9B, 0xF3, 0x59, 0xF1, 0xD6, 0xE0, 0x7A, 0x06, 0x56, 0x3C, 0x3D, 0xBD, 0x15, 0x81, 0xBB, 0x3A, 0xEB, 0x85, 0x0E, 0x12, 0xAA, 0xB1, 0x60, 0x59, 0x6C, 0xBE, 0x40, 0x8E, 0x8D, 0xAE, 0x01, 0x96, 0x28, 0x7A, 0x13, 0x71, 0x3C, 0x53, 0x87, 0x35, 0x93, 0xBA, 0xE2, 0x25, 0xEA, 0xB5, 0x35, 0xAE, 0x50, 0x4E, 0xBE, 0xE0, 0xDD, 0x0C, 0xBA, 0x8A, 0xC3, 0xF0, 0x24, 0x17, 0xF6, 0xF0, 0xE4, 0xCC, 0xDB, 0xBD, 0x27, 0x2B, 0xB7, 0xAB, 0xC1, 0x95, 0x62, 0xB0, 0xBF, 0x80, 0x95, 0xA8, 0x08, 0x02, 0x7F, 0xD1, 0xD6, 0x2B, 0x77, 0x8D, 0x1C, 0x6E, 0xCE, 0xA5, 0xD9, 0xDA, 0x5D, 0xD3, 0xE6, 0x8B, 0xB5, 0xE7, 0x79, 0x41, 0xA6, 0xD3, 0x9E, 0x7D, 0x27, 0xBC, 0x49, 0x99, 0x85, 0x0B, 0xF1, 0x0E, 0x45, 0x1E, 0xFB, 0x2A, 0xF7, 0xD7, 0x0E, 0x7C, 0xCF, 0xF0, 0xF4, 0x52, 0x48, 0x18, 0x7B, 0x11, 0x4B, 0xF1, 0xB9, 0xA9, 0x81, 0xE9, 0x27, 0x0A, 0x37, 0xC3, 0x55, 0xBD, 0xB4, 0x55, 0xDB, 0xAD, 0xB7, 0xDF, 0x79, 0x9F, 0x46, 0xB5, 0x95, 0x4B, 0x79, 0x7B, 0x11, 0xD9, 0x2D, 0x13, 0xE3, 0x08, 0xD5, 0xA1, 0x84, 0xA0, 0x41, 0x3B, 0x6E, 0x11, 0xD3, 0x36, 0xF9, 0x7A, 0x55, 0x54, 0x10, 0xDF, 0x06, 0xE1, 0x4C, 0xD7, 0x57, 0x49, 0xBD, 0x66, 0x69, 0x7D, 0x1B, 0xA0, 0xE1, 0x83, 0x68, 0x08, 0x1D, 0xA0, 0xFD, 0x34, 0x86, 0x9E, 0x0D, 0xC1, 0x20, 0x1B, 0x65, 0x75, 0xDD, 0x3B, 0x5F, 0x73, 0xCA, 0xC2, 0x83, 0xFF, 0xFF, 0xE8, 0x6A, 0x51, 0xD8, 0x00, 0x00, 0xB2, 0x07, 0x44, 0xE9, 0x17, 0x33, 0x4B, 0x84, 0x00, 0x01, 0xF3, 0x02, 0xC9, 0x03, 0x00, 0x00, 0xDF, 0xF3, 0x90, 0x23, 0xB1, 0xC4, 0x67, 0xFB, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_lzma2_8) { // "bad-1-lzma2-8.xz is like good-1-lzma2-4.xz but doesn't set new // properties in the third LZMA2 chunk." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x04, 0xE6, 0xD6, 0xB4, 0x46, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0xE0, 0x00, 0xBB, 0x00, 0xA1, 0x5D, 0x00, 0x26, 0x1B, 0xCA, 0x46, 0x67, 0x5A, 0xF2, 0x77, 0xB8, 0x7D, 0x86, 0xD8, 0x41, 0xDB, 0x05, 0x35, 0xCD, 0x83, 0xA5, 0x7C, 0x12, 0xA5, 0x05, 0xDB, 0x90, 0xBD, 0x2F, 0x14, 0xD3, 0x71, 0x72, 0x96, 0xA8, 0x8A, 0x7D, 0x84, 0x56, 0x71, 0x8D, 0x6A, 0x22, 0x98, 0xAB, 0x9E, 0x3D, 0x90, 0x80, 0x2D, 0xC7, 0x5E, 0x0C, 0x12, 0x52, 0xD3, 0x3F, 0x07, 0x08, 0x7B, 0x1C, 0xA4, 0x77, 0xF3, 0x13, 0xB8, 0x17, 0xC0, 0xEE, 0x91, 0x73, 0xCA, 0xBC, 0xCF, 0xEB, 0x34, 0x66, 0xAC, 0x48, 0x9B, 0x69, 0xD9, 0x93, 0x07, 0xAE, 0xCE, 0x50, 0xAF, 0x68, 0x09, 0x2F, 0x5B, 0x88, 0x1F, 0xC2, 0x08, 0xA2, 0x2C, 0x58, 0x45, 0xB0, 0xFF, 0x62, 0x09, 0xEB, 0xEE, 0xDB, 0x63, 0x4F, 0x6F, 0xE0, 0xF3, 0x1F, 0xCF, 0x12, 0x37, 0x98, 0x96, 0x4E, 0xF6, 0xF2, 0xB2, 0xFB, 0x6E, 0xAF, 0x44, 0x02, 0xE2, 0x22, 0xDE, 0xD5, 0xE6, 0x34, 0x97, 0x39, 0xA3, 0x45, 0x2F, 0xAE, 0x99, 0x2F, 0x79, 0x69, 0x8F, 0xE9, 0x37, 0x89, 0x48, 0xFE, 0xCC, 0x7E, 0xEA, 0xA9, 0x28, 0xAD, 0xC3, 0xE6, 0xDC, 0xB9, 0xDA, 0xAA, 0x16, 0x7E, 0x01, 0x00, 0x26, 0x6C, 0x61, 0x62, 0x6F, 0x72, 0x69, 0x73, 0x20, 0x6E, 0x69, 0x73, 0x69, 0x20, 0x75, 0x74, 0x20, 0x61, 0x6C, 0x69, 0x71, 0x75, 0x69, 0x70, 0x20, 0x65, 0x78, 0x20, 0x65, 0x61, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x0A, 0xA0, 0x00, 0xE5, 0x00, 0xBD, 0x00, 0x31, 0x9B, 0xCA, 0x19, 0xC5, 0x54, 0xEC, 0xB6, 0x54, 0xE7, 0xB1, 0x7D, 0xC4, 0x57, 0x9E, 0x6C, 0x89, 0xAD, 0x4A, 0x6D, 0x16, 0xD8, 0x3C, 0x05, 0x94, 0x10, 0x16, 0x99, 0x38, 0x21, 0xA3, 0xB9, 0xC5, 0x80, 0xFF, 0xFC, 0xEE, 0xD4, 0xD5, 0x3F, 0xDD, 0x8C, 0xD7, 0x3D, 0x8F, 0x76, 0xEC, 0x88, 0xAA, 0x32, 0xAB, 0x65, 0xD4, 0x38, 0xEF, 0xF7, 0xF9, 0x8A, 0xBF, 0xF7, 0xF8, 0xA5, 0x56, 0xD7, 0x6D, 0xD7, 0x3F, 0x85, 0x0B, 0x9E, 0x3F, 0xE2, 0x47, 0x68, 0x22, 0x08, 0x05, 0x35, 0xB8, 0x41, 0x72, 0xF9, 0xDB, 0xBE, 0xB7, 0x8E, 0x86, 0xBF, 0x43, 0x4B, 0x8E, 0x0D, 0x43, 0x2F, 0x41, 0x69, 0xDF, 0x61, 0x0C, 0xC4, 0xE8, 0x37, 0x08, 0x4A, 0xDE, 0xC2, 0x76, 0x16, 0xB8, 0x48, 0x4E, 0x9E, 0xB9, 0x53, 0x50, 0x1F, 0x33, 0x83, 0xE8, 0x29, 0xA0, 0x67, 0xC8, 0x66, 0x3A, 0x7F, 0x22, 0x12, 0x62, 0xFB, 0x47, 0xE4, 0xBC, 0xF4, 0x51, 0x0F, 0x15, 0x88, 0x49, 0xD8, 0xCA, 0x0B, 0x25, 0x8B, 0x5E, 0xE8, 0xDA, 0xFD, 0x38, 0xC0, 0xCE, 0x4C, 0x73, 0x1B, 0xFF, 0xD0, 0x9B, 0xE8, 0x4C, 0xB7, 0x13, 0xF8, 0x37, 0x99, 0xE2, 0xDA, 0x9C, 0x2F, 0xB5, 0xEA, 0xB8, 0xA5, 0x8D, 0xEA, 0x57, 0x82, 0x9B, 0x25, 0xCA, 0xFB, 0xF6, 0x88, 0x0A, 0x9B, 0xDF, 0x41, 0x03, 0x6E, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x07, 0x44, 0xE9, 0x17, 0x33, 0x4B, 0x84, 0x00, 0x01, 0xAA, 0x03, 0xC9, 0x03, 0x00, 0x00, 0x50, 0x83, 0x71, 0x35, 0xB1, 0xC4, 0x67, 0xFB, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_lzma2_9) { // "bad-1-lzma2-9.xz has LZMA2 stream that is truncated at the end of // a LZMA2 chunk (no end marker). The uncompressed size of the partial // LZMA2 stream exceeds the value stored in the Block Header." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x03, 0xC0, 0x14, 0x0D, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3B, 0x15, 0x10, 0x0D, 0x01, 0x00, 0x0C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x02, 0xFF, 0xFF, 0x78, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x28, 0x0D, 0x3C, 0x67, 0x6A, 0x03, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_lzma2_10) { // "bad-1-lzma2-10.xz has LZMA2 stream that, from point of view of a // LZMA2 decoder, extends past the end of Block (and even the end of // the file). Uncompressed Size in Block Header is bigger than the // invalid LZMA2 stream may produce (even if a decoder reads until // the end of the file). The Check type is None to nullify certain // simple size-based sanity checks in a Block decoder." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x00, 0xFF, 0x12, 0xD9, 0x41, 0x02, 0xC0, 0x10, 0x30, 0x21, 0x01, 0x08, 0x00, 0xE6, 0xD5, 0x78, 0x98, 0x01, 0xFF, 0xFF, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x01, 0x1C, 0x30, 0xDA, 0xD8, 0x28, 0xE0, 0x06, 0x72, 0x9E, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_lzma2_11) { // "bad-1-lzma2-11.xz has LZMA2 stream that lacks the end of // payload marker. When Compressed Size bytes have been decoded, // Uncompressed Size bytes of output will have been produced but // the LZMA2 decoder doesn't indicate end of stream." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x00, 0xFF, 0x12, 0xD9, 0x41, 0x03, 0xC0, 0x10, 0x0D, 0x21, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0xF7, 0x6A, 0x9F, 0x01, 0x00, 0x0C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x20, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x01, 0x20, 0x0D, 0x34, 0xED, 0xB3, 0xCB, 0x06, 0x72, 0x9E, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_stream_flags_1) { // "bad-1-stream_flags-1.xz has different Stream Flags in Stream Header // and Stream Footer." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x2A, 0x13, 0x90, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_stream_flags_2) { // "bad-1-stream_flags-2.xz has wrong CRC32 in Stream Header." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x76, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_stream_flags_3) { // "bad-1-stream_flags-3.xz has wrong CRC32 in Stream Footer." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x98, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_vli_1) { // "bad-1-vli-1.xz has two-byte variable-length integer in the // Uncompressed Size field in Block Header while one-byte would be enough // for that value. It's important that the file gets rejected due to too // big integer encoding instead of due to Uncompressed Size not matching // the value stored in the Block Header. That is, the decoder must not // try to decode the Compressed Data field." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x03, 0x80, 0x8D, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x48, 0xA9, 0x17, 0x01, 0x00, 0x0C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x25, 0x0D, 0x71, 0x19, 0xC4, 0xB6, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_1_vli_2) { // "bad-1-vli-2.xz has ten-byte variable-length integer as Uncompressed // Size in Block Header. It's important that the file gets rejected due // to too big integer encoding instead of due to Uncompressed Size not // matching the value stored in the Block Header. That is, the decoder // must not try to decode the Compressed Data field." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x04, 0x80, 0x8D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01, 0x21, 0x01, 0x08, 0x00, 0xD2, 0x64, 0xF0, 0x5C, 0x01, 0x00, 0x0C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x29, 0x0D, 0x7D, 0x56, 0x71, 0x1A, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_2_compressed_data_padding) { // "bad-2-compressed_data_padding.xz has non-null byte in the padding of // the Compressed Data field of the first Block." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00, 0x01, 0x16, 0x35, 0x96, 0x31, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0xDD, 0xD1, 0xCA, 0x53, 0x00, 0x02, 0x1A, 0x06, 0x1B, 0x07, 0x00, 0x00, 0x06, 0xDC, 0xE7, 0x5D, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_2_index_1) { // "bad-2-index-1.xz has wrong Unpadded Sizes in Index." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00, 0x00, 0x16, 0x35, 0x96, 0x31, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0xDD, 0xD1, 0xCA, 0x53, 0x00, 0x02, 0x1B, 0x06, 0x1A, 0x07, 0x00, 0x00, 0xC6, 0x68, 0x07, 0x2E, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_2_index_2) { // "bad-2-index-2.xz has wrong Uncompressed Sizes in Index." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00, 0x00, 0x16, 0x35, 0x96, 0x31, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0xDD, 0xD1, 0xCA, 0x53, 0x00, 0x02, 0x1A, 0x0D, 0x1B, 0x00, 0x00, 0x00, 0x92, 0xFB, 0x78, 0x2F, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_2_index_3) { // "bad-2-index-3.xz has non-null byte in Index Padding." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00, 0x00, 0x16, 0x35, 0x96, 0x31, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0xDD, 0xD1, 0xCA, 0x53, 0x00, 0x02, 0x1A, 0x06, 0x1B, 0x07, 0x00, 0x01, 0x90, 0xEC, 0xE0, 0x2A, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_2_index_4) { // "bad-2-index-4.xz wrong CRC32 in Index." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00, 0x00, 0x16, 0x35, 0x96, 0x31, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0xDD, 0xD1, 0xCA, 0x53, 0x00, 0x02, 0x1A, 0x06, 0x1B, 0x07, 0x00, 0x00, 0x06, 0xDC, 0xE7, 0x5C, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: The index is currently not checked against the stored CRC32. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_bad_2_index_5) { // "bad-2-index-5.xz has zero as Unpadded Size. It is important that the // file gets rejected specifically due to Unpadded Size having an invalid // value." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00, 0x00, 0x16, 0x35, 0x96, 0x31, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0xDD, 0xD1, 0xCA, 0x53, 0x00, 0x02, 0x35, 0x06, 0x00, 0x07, 0x00, 0x00, 0x7B, 0xBB, 0x05, 0x2C, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_bad_3_index_uncomp_overflow) { // "bad-3-index-uncomp-overflow.xz has Index whose Uncompressed Size // fields have huge values whose sum exceeds the maximum allowed size // of 2^63 - 1 bytes. In this file the sum is exactly 2^64." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x8F, 0x98, 0x41, 0x9C, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00, 0x00, 0x16, 0x35, 0x96, 0x31, 0x02, 0x00, 0x21, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x8F, 0x98, 0x41, 0x9C, 0x01, 0x00, 0x04, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x00, 0x00, 0x00, 0x00, 0x47, 0x3E, 0xB6, 0xFB, 0x02, 0x00, 0x21, 0x01, 0x0C, 0x00, 0x00, 0x00, 0x8F, 0x98, 0x41, 0x9C, 0x01, 0x00, 0x01, 0x21, 0x0A, 0x00, 0x00, 0x00, 0x02, 0xEE, 0x93, 0x2D, 0x00, 0x03, 0x1A, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x16, 0x02, 0x32, 0x89, 0xCE, 0x34, 0x28, 0x72, 0x9C, 0x10, 0x06, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } auto const xz_utils_hello_world = "Hello\nWorld!\n"sv; auto const xz_utils_lorem_ipsum = R"(Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. )"sv; TEST_CASE(xz_utils_good_0cat_empty) { // "good-0cat-empty.xz has two zero-Block Streams concatenated without // Stream Padding." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A, 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.size(), 0ul); } TEST_CASE(xz_utils_good_0catpad_empty) { // "good-0catpad-empty.xz has two zero-Block Streams concatenated with // four-byte Stream Padding between the Streams." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A, 0x00, 0x00, 0x00, 0x00, 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.size(), 0ul); } TEST_CASE(xz_utils_good_0_empty) { // "good-0-empty.xz has one Stream with no Blocks." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.size(), 0ul); } TEST_CASE(xz_utils_good_0pad_empty) { // "good-0pad-empty.xz has one Stream with no Blocks followed by // four-byte Stream Padding." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x00, 0x00, 0x00, 0x00, 0x1C, 0xDF, 0x44, 0x21, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A, 0x00, 0x00, 0x00, 0x00 }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.size(), 0ul); } TEST_CASE(xz_utils_good_1_3delta_lzma2) { // "good-1-3delta-lzma2.xz has three Delta filters and LZMA2." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x04, 0xE6, 0xD6, 0xB4, 0x46, 0x04, 0x03, 0x03, 0x01, 0x00, 0x03, 0x01, 0x01, 0x03, 0x01, 0x02, 0x21, 0x01, 0x08, 0x00, 0x00, 0xBC, 0x15, 0x65, 0xC6, 0x01, 0x01, 0xC8, 0x4C, 0x23, 0xB7, 0x84, 0xE2, 0x09, 0x71, 0x4F, 0xFA, 0xBA, 0xA1, 0xF7, 0x51, 0x63, 0x08, 0xAC, 0xAE, 0xF2, 0x58, 0x42, 0x0D, 0x66, 0xEE, 0xA8, 0x01, 0xCD, 0x60, 0x2E, 0x88, 0x58, 0xD7, 0x6E, 0xDB, 0x3D, 0x26, 0x00, 0x05, 0xF1, 0xFB, 0xAF, 0x34, 0x67, 0x17, 0xC0, 0x9F, 0x3F, 0xF9, 0xFC, 0x0D, 0x0E, 0x03, 0xA4, 0xE6, 0xAF, 0x69, 0xB1, 0x62, 0x9E, 0x47, 0x97, 0x43, 0xC3, 0x2F, 0x47, 0xA3, 0xA3, 0xF5, 0x04, 0x5A, 0xC0, 0x9B, 0x3D, 0x01, 0xCC, 0x5B, 0x3A, 0xFA, 0xB3, 0xC2, 0x4C, 0x9D, 0x4F, 0x57, 0xFD, 0xBB, 0xAF, 0x53, 0xFF, 0x06, 0xFF, 0xF5, 0xA7, 0x51, 0x5E, 0xA4, 0x9C, 0x63, 0xB4, 0xB4, 0x62, 0xF7, 0x47, 0xA0, 0x50, 0x6E, 0xAF, 0xE3, 0x0B, 0x52, 0xC3, 0xA7, 0x37, 0xC0, 0x54, 0x49, 0x01, 0xB9, 0xB4, 0xFF, 0x3B, 0x5F, 0x04, 0xAF, 0xBB, 0x28, 0xCC, 0xFF, 0x84, 0x64, 0x71, 0xBE, 0x30, 0x3F, 0xD5, 0x5B, 0x30, 0xA9, 0x61, 0x7F, 0xA6, 0x27, 0x53, 0xB5, 0xBF, 0x00, 0x53, 0x3D, 0xFB, 0xBA, 0xB3, 0x5E, 0xBB, 0xF9, 0x81, 0x49, 0xBB, 0x74, 0xA9, 0xA1, 0x4E, 0xFD, 0xBC, 0xA6, 0x4C, 0xF1, 0xBF, 0x54, 0x66, 0xEF, 0xA4, 0xAD, 0x51, 0x20, 0xE3, 0x0F, 0xEE, 0x0C, 0x02, 0xA4, 0x63, 0x3B, 0xFF, 0xA8, 0xC7, 0x56, 0x02, 0xAF, 0xDD, 0xB1, 0x50, 0xC1, 0x67, 0xF7, 0x4B, 0xEF, 0xB4, 0x5A, 0x47, 0x06, 0xB7, 0x5F, 0xA3, 0x4D, 0xAA, 0xE3, 0x17, 0x65, 0xBB, 0xA8, 0x30, 0x06, 0xB5, 0x52, 0x60, 0xA7, 0xF4, 0xF1, 0x17, 0x15, 0xF9, 0x41, 0xAD, 0xB7, 0x3A, 0x15, 0xB8, 0xEA, 0x9F, 0x66, 0xC7, 0x51, 0xD1, 0x61, 0x19, 0xED, 0x08, 0xBC, 0xFF, 0x5B, 0x71, 0xF1, 0x6F, 0x7A, 0x67, 0x8E, 0x05, 0xA6, 0x55, 0x9A, 0x71, 0xFE, 0x9C, 0xA2, 0x04, 0x5D, 0x60, 0xFB, 0xA7, 0xB6, 0xF2, 0x4E, 0x51, 0xBE, 0x07, 0xEA, 0x50, 0xC2, 0xA7, 0x48, 0xFB, 0x1E, 0xF8, 0xEE, 0x11, 0xFD, 0x06, 0x9E, 0xE9, 0xB5, 0x66, 0x74, 0x9E, 0x2C, 0x54, 0xBF, 0xB7, 0x54, 0xE2, 0x11, 0x09, 0xB6, 0x56, 0x30, 0x09, 0xA9, 0xD0, 0xFE, 0x2C, 0x5E, 0x0C, 0xAA, 0x59, 0x96, 0x67, 0x05, 0xA9, 0xBB, 0x38, 0xB0, 0x46, 0x60, 0x0F, 0xAC, 0xAE, 0x37, 0xC0, 0x4C, 0x65, 0xAE, 0x88, 0x5C, 0xBF, 0xBC, 0x42, 0xE1, 0x7B, 0xC1, 0x35, 0x4A, 0xF5, 0xBE, 0xA3, 0x16, 0x62, 0x34, 0x02, 0xAB, 0xB5, 0x5B, 0x03, 0x03, 0x9F, 0xEC, 0x7F, 0x86, 0xD1, 0x66, 0xDF, 0x3C, 0x17, 0xEC, 0x0A, 0xB8, 0x4A, 0x3C, 0x14, 0xBA, 0x5F, 0x97, 0x38, 0x0A, 0xC1, 0xBC, 0x4F, 0xF0, 0x11, 0xAE, 0x36, 0x51, 0x0A, 0xB7, 0x9A, 0x4C, 0x31, 0xF0, 0xFC, 0xA7, 0xE7, 0xB8, 0x58, 0xC4, 0xF9, 0x3A, 0xB5, 0xFC, 0xA7, 0xAE, 0x5A, 0x16, 0x07, 0xA8, 0xE0, 0x96, 0x5F, 0xB8, 0x69, 0xA5, 0x9D, 0x55, 0xB6, 0xFB, 0x07, 0x4B, 0xB4, 0x9A, 0x07, 0x6E, 0x4B, 0xE8, 0x53, 0x16, 0x9D, 0xFE, 0xB1, 0xBA, 0x52, 0xF2, 0xBF, 0xEF, 0x9D, 0x5E, 0xC2, 0x56, 0xE8, 0x5D, 0xFB, 0x04, 0xA2, 0x5B, 0x53, 0xFD, 0xB7, 0xAA, 0x5B, 0xB1, 0x36, 0x56, 0x0B, 0xC1, 0x57, 0x8B, 0x51, 0xBB, 0x05, 0x0A, 0x49, 0x54, 0xF9, 0x8D, 0x17, 0xCD, 0xB9, 0x41, 0xDD, 0xBC, 0x04, 0x34, 0x00, 0x00, 0x00, 0x00, 0xB2, 0x07, 0x44, 0xE9, 0x17, 0x33, 0x4B, 0x84, 0x00, 0x01, 0xE9, 0x03, 0xC9, 0x03, 0x00, 0x00, 0x92, 0xFB, 0xBD, 0xBC, 0xB1, 0xC4, 0x67, 0xFB, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: This uses the currently unimplemented delta filter. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_good_1_arm64_lzma2_1) { // "good-1-arm64-lzma2-1.xz uses the ARM64 filter and LZMA2. The // uncompressed data is constructed so that it tests integer // wrap around and sign extension." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x01, 0x0A, 0x00, 0x21, 0x01, 0x08, 0x00, 0xA2, 0xD8, 0x7E, 0xF1, 0xE0, 0x21, 0x7F, 0x01, 0xC3, 0x6E, 0x00, 0x00, 0x68, 0x23, 0x88, 0x71, 0x63, 0xC2, 0x8F, 0x53, 0x0A, 0xE6, 0xB1, 0xDF, 0xD0, 0x8A, 0xAE, 0x1B, 0xA1, 0xB0, 0x78, 0xAB, 0x28, 0x43, 0x13, 0x5E, 0x7F, 0xE4, 0x97, 0xC5, 0x69, 0xCF, 0xC1, 0x0A, 0xCD, 0xDA, 0x89, 0x2E, 0x3A, 0x9E, 0xF2, 0xAC, 0x4F, 0x83, 0xDC, 0x79, 0xB5, 0x0B, 0xC3, 0xFB, 0xF1, 0xF8, 0x14, 0x14, 0xBA, 0xA1, 0xF6, 0xC3, 0x11, 0x97, 0x9E, 0x53, 0x71, 0x7A, 0x6B, 0x4D, 0xDE, 0x7F, 0xAB, 0xB5, 0x81, 0x19, 0xD2, 0x87, 0xB3, 0x8E, 0x59, 0xCC, 0xAD, 0x32, 0xF5, 0x73, 0x9A, 0x90, 0x0D, 0x99, 0x7D, 0x46, 0x55, 0x52, 0xA0, 0x15, 0x03, 0xE7, 0x1C, 0xF0, 0x97, 0x4F, 0xAF, 0xC1, 0x8B, 0xCA, 0x2B, 0x76, 0x63, 0xC6, 0xD3, 0xDC, 0x68, 0xD9, 0xBF, 0x04, 0x20, 0x1A, 0x1D, 0x80, 0x25, 0x28, 0x83, 0x30, 0x32, 0xA3, 0x64, 0xE4, 0x26, 0xDD, 0xC0, 0x16, 0xD6, 0x8B, 0xB0, 0x11, 0x37, 0x88, 0xBD, 0xE2, 0xD9, 0xBC, 0x2D, 0xB7, 0x45, 0x3C, 0xCA, 0x5A, 0x0F, 0xAA, 0x26, 0x98, 0x9D, 0xB9, 0xF8, 0x18, 0xA3, 0x55, 0xCD, 0xAE, 0x02, 0x30, 0x27, 0xF2, 0x62, 0xA8, 0x0D, 0x0D, 0x20, 0x4D, 0xB1, 0x80, 0xAA, 0x48, 0x92, 0x7C, 0x98, 0x99, 0x5A, 0x8E, 0x0F, 0x5F, 0xF8, 0x58, 0x7E, 0x5F, 0x79, 0x36, 0xF3, 0xD8, 0x3C, 0xEF, 0x03, 0xD4, 0x50, 0x2A, 0xB7, 0xC9, 0x3A, 0x3C, 0xA6, 0xEB, 0x33, 0x8A, 0xD7, 0xFB, 0x8C, 0xBE, 0x31, 0xD3, 0x76, 0x72, 0x2E, 0x6B, 0x89, 0x1F, 0x27, 0x74, 0xE1, 0x02, 0xF7, 0x5D, 0x1E, 0x59, 0xE0, 0x6F, 0xE1, 0xDD, 0xCC, 0xF9, 0x90, 0xCB, 0x27, 0x59, 0xA0, 0xA3, 0x6F, 0x96, 0x73, 0x82, 0xCF, 0x4D, 0x71, 0x21, 0x1E, 0x4E, 0xBF, 0xCF, 0xD0, 0x29, 0xB2, 0xCF, 0x56, 0x6E, 0x21, 0x8F, 0xC8, 0x77, 0x95, 0xEB, 0x6A, 0xEF, 0x3C, 0xDC, 0x00, 0x76, 0xB0, 0x94, 0x63, 0x70, 0x8C, 0x94, 0x5F, 0x7F, 0x1F, 0x83, 0xF9, 0x1F, 0xCE, 0x64, 0x4F, 0x45, 0xBD, 0xF8, 0x13, 0x5A, 0x78, 0x0C, 0x1A, 0xDF, 0xE4, 0x0B, 0xDC, 0xBA, 0x07, 0x33, 0xEC, 0x53, 0xA9, 0xFB, 0x31, 0xE5, 0xCC, 0xC3, 0x87, 0x95, 0x90, 0xF5, 0x93, 0x8E, 0x02, 0xEE, 0xE3, 0x56, 0xA6, 0xF9, 0xD3, 0xA3, 0x78, 0xA5, 0x08, 0x24, 0xBC, 0x1E, 0x2A, 0xA9, 0x99, 0x78, 0x4B, 0xE8, 0xBB, 0x73, 0x47, 0xCE, 0x08, 0x0C, 0x5A, 0x01, 0xCE, 0xE1, 0xC5, 0x9D, 0x85, 0xDC, 0xD4, 0x19, 0x59, 0xB5, 0x3D, 0xAF, 0xF5, 0xA4, 0xCF, 0x66, 0x12, 0xFD, 0x5B, 0xFE, 0x0A, 0x7A, 0xEE, 0xF7, 0x61, 0x81, 0x0A, 0x06, 0x09, 0x5D, 0xCB, 0x10, 0xC5, 0x6F, 0x68, 0x4F, 0xED, 0xED, 0x97, 0xC7, 0x37, 0x1F, 0xDE, 0x6D, 0x2D, 0xC2, 0x26, 0xA0, 0xE6, 0x94, 0x18, 0x06, 0xC3, 0xA8, 0xC0, 0x0F, 0x4C, 0xE3, 0x1C, 0x0A, 0x9B, 0x03, 0xF7, 0x10, 0xB6, 0x81, 0xAB, 0x8A, 0x5D, 0xAE, 0x0C, 0xAA, 0xA8, 0xAB, 0xB1, 0x65, 0x55, 0x7F, 0x33, 0x52, 0xF6, 0x23, 0x0F, 0xAC, 0x21, 0xA4, 0xC5, 0xF1, 0x44, 0x9D, 0xE0, 0xB7, 0x39, 0x6D, 0x2D, 0x48, 0x20, 0x8C, 0x81, 0x51, 0x50, 0x60, 0xEF, 0xA1, 0x00, 0x71, 0xD9, 0xE3, 0xB5, 0x4F, 0xFD, 0x57, 0xB6, 0x0E, 0xFC, 0x40, 0x48, 0xD3, 0x00, 0x00, 0xA0, 0x7C, 0xE1, 0xD4, 0x00, 0x01, 0xDB, 0x03, 0x80, 0x43, 0x00, 0x00, 0x43, 0xC7, 0x89, 0x63, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: This uses the currently unimplemented arm64 filter. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_good_1_arm64_lzma2_2) { // "good-1-arm64-lzma2-2.xz is like good-1-arm64-lzma2-1.xz but with // non-zero start offset." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x03, 0x01, 0x0A, 0x04, 0x00, 0xF0, 0xFF, 0xFF, 0x21, 0x01, 0x08, 0x00, 0x67, 0x74, 0x40, 0x1C, 0xE0, 0x21, 0x7F, 0x01, 0xA6, 0x6E, 0x00, 0x00, 0x3F, 0x1E, 0xEC, 0xFA, 0xC9, 0x8B, 0xE0, 0xE3, 0xD4, 0xE5, 0xEC, 0x75, 0x8B, 0x62, 0x01, 0xD1, 0xB9, 0xAE, 0x17, 0xB3, 0xE1, 0x01, 0x82, 0xB1, 0x88, 0x36, 0x96, 0x7C, 0xD3, 0x5E, 0x60, 0x14, 0x52, 0xE3, 0xD7, 0x99, 0x0D, 0x4E, 0x26, 0x37, 0x2E, 0xAA, 0xF2, 0xAE, 0x49, 0x93, 0xF8, 0xCF, 0x48, 0x00, 0xAF, 0x88, 0xFE, 0x05, 0x57, 0xE7, 0x5C, 0xB8, 0x85, 0xAA, 0x38, 0x18, 0x49, 0x6D, 0x35, 0xC7, 0x64, 0xC5, 0xD5, 0x19, 0xAB, 0x99, 0x05, 0x8F, 0x64, 0x29, 0x5B, 0x39, 0xE3, 0x0A, 0xC0, 0x1C, 0xE6, 0x69, 0xF4, 0x7A, 0xCC, 0x0A, 0x06, 0xDD, 0xE5, 0x26, 0x53, 0xC9, 0xA9, 0xAF, 0x2F, 0x44, 0x22, 0x3D, 0xE5, 0x96, 0x3B, 0x40, 0x50, 0xE5, 0x00, 0xE1, 0xF3, 0x8E, 0x02, 0x10, 0xA7, 0xA7, 0x3F, 0x43, 0x22, 0x2D, 0xC1, 0xAA, 0x2F, 0x3A, 0xDA, 0xE7, 0xBD, 0x72, 0xD4, 0x86, 0xD6, 0x16, 0x22, 0x35, 0xE3, 0x2D, 0x4F, 0x05, 0xF3, 0xE6, 0x36, 0x16, 0xB5, 0x98, 0x6D, 0x56, 0x65, 0x47, 0x66, 0x0F, 0x35, 0x93, 0xA2, 0xFE, 0xE0, 0x2F, 0x34, 0xAD, 0xE9, 0x34, 0x05, 0x79, 0x4D, 0x8A, 0x10, 0xF1, 0xDA, 0xF3, 0xA7, 0xC8, 0xD7, 0x24, 0xEC, 0x29, 0xD7, 0x7B, 0xDC, 0x39, 0xE5, 0xAC, 0x30, 0xE7, 0x3D, 0x8F, 0xC2, 0x33, 0x6A, 0x63, 0x53, 0x0A, 0xD6, 0xF0, 0x45, 0xBA, 0x92, 0xFF, 0x31, 0xCC, 0x3F, 0x55, 0x6F, 0xE8, 0xC7, 0xF0, 0xFC, 0x9C, 0xA2, 0xEF, 0x4B, 0x6C, 0xCF, 0x67, 0xD9, 0xAF, 0x7C, 0x1D, 0xB8, 0x39, 0xFB, 0x48, 0xC6, 0x0D, 0x7D, 0x97, 0x73, 0xB9, 0x58, 0x18, 0x20, 0x51, 0x86, 0xF1, 0x70, 0xD6, 0x7E, 0x3B, 0xAA, 0xFB, 0x2B, 0x0E, 0x9A, 0x99, 0x26, 0x58, 0x71, 0x8A, 0xE6, 0x69, 0xF3, 0x79, 0xDE, 0xDE, 0x74, 0xED, 0x86, 0x4D, 0xA1, 0xFE, 0xDF, 0x89, 0x48, 0x98, 0xDF, 0xF9, 0x5D, 0x4B, 0x07, 0x1B, 0x23, 0x20, 0x51, 0xC1, 0x79, 0xC2, 0x89, 0x70, 0x9D, 0xA6, 0x59, 0x32, 0xF4, 0xA6, 0xB4, 0x61, 0xBB, 0xB4, 0x9E, 0xA4, 0xD7, 0x6B, 0x84, 0x73, 0x72, 0x03, 0x3F, 0x87, 0xE3, 0x17, 0x67, 0xC3, 0xF9, 0x9B, 0xDA, 0x4C, 0xCB, 0x6A, 0x1C, 0xAC, 0x85, 0xF4, 0x93, 0xBE, 0x6A, 0x76, 0x6C, 0xB1, 0x0E, 0xDA, 0x3C, 0x75, 0x71, 0x97, 0xE8, 0x22, 0x2B, 0xB0, 0x1F, 0x32, 0x89, 0x10, 0x19, 0x58, 0xF8, 0xF8, 0xC2, 0x6D, 0x9B, 0x74, 0x07, 0xE5, 0x4F, 0x5F, 0x0C, 0xF0, 0x06, 0x48, 0x77, 0x58, 0xD5, 0x3E, 0xD4, 0xD1, 0x58, 0xBD, 0x18, 0xE6, 0xCF, 0x22, 0xD7, 0x94, 0xA9, 0xD2, 0x20, 0xD5, 0x06, 0xE2, 0x1B, 0x57, 0xF9, 0x0D, 0xA5, 0x02, 0x5C, 0x41, 0x8E, 0x0C, 0xBF, 0x1D, 0x78, 0xE3, 0x68, 0xA1, 0x86, 0x36, 0xCE, 0x0E, 0xCB, 0x26, 0xBD, 0x48, 0x73, 0x2D, 0xA8, 0x9D, 0x2A, 0xA7, 0x40, 0x29, 0xCA, 0xE7, 0xC7, 0xC4, 0x57, 0x8B, 0xAA, 0xE3, 0x8F, 0xC6, 0x54, 0x81, 0xB4, 0x1A, 0x04, 0x4F, 0x6E, 0x22, 0x77, 0x9C, 0x5A, 0xDF, 0x13, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x7C, 0xE1, 0xD4, 0x00, 0x01, 0xC2, 0x03, 0x80, 0x43, 0x00, 0x00, 0x10, 0x94, 0x50, 0x47, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: This uses the currently unimplemented arm64 filter. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_good_1_block_header_1) { // "good-1-block_header-1.xz has both Compressed Size and Uncompressed // Size in the Block Header. This has also four extra bytes of Header // Padding." Array const compressed { // Stream Header 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, // Magic 0x00, 0x01, // Stream Flags 0x69, 0x22, 0xDE, 0x36, // CRC32 // Block Header 0x03, // Block Header Size 0xC0, // Block Flags (one filter, compressed size and uncompressed size present) 0x11, // Compressed Size 0x0D, // Uncompressed Size // Filter 0 Flags 0x21, // Filter ID 0x01, // Size of Properties 0x08, // Filter Properties 0x00, 0x00, 0x00, 0x00, 0x00, // Header Padding 0x7F, 0xDE, 0x39, 0xEB, // CRC32 // Compressed Data (LZMA2) // Uncompressed chunk with dictionary reset 0x01, // Control Byte 0x00, 0x0C, // 16-bit data size minus one (big-endian) 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, // End of LZMA2 stream 0x00, // Block Padding 0x00, 0x00, 0x00, // Uncompressed Data Check (CRC32) 0x43, 0xA3, 0xA2, 0x15, // Index 0x00, // Index Indicator 0x01, // Number of Records (multibyte integer) // Record 0 0x25, // Unpadded Size (multibyte integer) 0x0D, // Uncompressed Size (multibyte integer) // CRC32 0x71, 0x19, 0xC4, 0xB6, // Stream Footer 0x90, 0x42, 0x99, 0x0D, // CRC32 0x01, 0x00, 0x00, 0x00, // Backward Size 0x00, 0x01, // Stream Flags 0x59, 0x5A, // Footer Magic Bytes }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_hello_world.bytes()); } TEST_CASE(xz_utils_good_1_block_header_2) { // "good-1-block_header-2.xz has known Compressed Size." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x40, 0x11, 0x21, 0x01, 0x08, 0x00, 0x00, 0x3A, 0x4C, 0x88, 0xE1, 0x01, 0x00, 0x0C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x21, 0x0D, 0x75, 0xDC, 0xA8, 0xD2, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_hello_world.bytes()); } TEST_CASE(xz_utils_good_1_block_header_3) { // "good-1-block_header-3.xz has known Uncompressed Size." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x80, 0x0D, 0x21, 0x01, 0x08, 0x00, 0x00, 0x51, 0x11, 0x81, 0x59, 0x01, 0x00, 0x0C, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x21, 0x0D, 0x75, 0xDC, 0xA8, 0xD2, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_hello_world.bytes()); } TEST_CASE(xz_utils_good_1_check_crc32) { // "good-1-check-crc32.xz has one Stream with one Block with two // uncompressed LZMA2 chunks and CRC32 check." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_hello_world.bytes()); } TEST_CASE(xz_utils_good_1_check_crc64) { // "good-1-check-crc64.xz is like good-1-check-crc32.xz but with CRC64." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x04, 0xE6, 0xD6, 0xB4, 0x46, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0xEF, 0x2E, 0x88, 0x11, 0x9D, 0x3F, 0x96, 0xCA, 0x00, 0x01, 0x28, 0x0D, 0x3C, 0x67, 0x6A, 0x03, 0x1F, 0xB6, 0xF3, 0x7D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_hello_world.bytes()); } TEST_CASE(xz_utils_good_1_check_none) { // "good-1-check-none.xz has one Stream with one Block with two // uncompressed LZMA2 chunks and no integrity check." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x00, 0xFF, 0x12, 0xD9, 0x41, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0x01, 0x20, 0x0D, 0x34, 0xED, 0xB3, 0xCB, 0x06, 0x72, 0x9E, 0x7A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_hello_world.bytes()); } TEST_CASE(xz_utils_good_1_check_sha256) { // "good-1-check-sha256.xz is like good-1-check-crc32.xz but with // SHA256." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x0A, 0xE1, 0xFB, 0x0C, 0xA1, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x8E, 0x59, 0x35, 0xE7, 0xE1, 0x33, 0x68, 0xCD, 0x96, 0x88, 0xFE, 0x8F, 0x48, 0xA0, 0x95, 0x52, 0x93, 0x67, 0x6A, 0x02, 0x15, 0x62, 0x58, 0x2C, 0x7E, 0x84, 0x8D, 0xAF, 0xE1, 0x3F, 0xB0, 0x46, 0x00, 0x01, 0x40, 0x0D, 0x93, 0x86, 0x4E, 0xAE, 0x18, 0x9B, 0x4B, 0x9A, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_hello_world.bytes()); } // "good-1-delta-lzma2.tiff.xz is an image file that compresses // better with Delta+LZMA2 than with plain LZMA2." // This test has not been added due to it having a filesize of 50.1 KiB. TEST_CASE(xz_utils_good_1_empty_bcj_lzma2) { // "good-1-empty-bcj-lzma2.xz has an empty Block that uses PowerPC BCJ // and LZMA2." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x01, 0x05, 0x00, 0x21, 0x01, 0x00, 0x00, 0x7F, 0xE0, 0xF1, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x3B, 0x96, 0x5F, 0x73, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: This uses the currently unimplemented PowerPC branch/call/jump filter. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_good_1_lzma2_1) { // "good-1-lzma2-1.xz has two LZMA2 chunks, of which the second sets // new properties." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0xE0, 0x00, 0xE2, 0x00, 0xB6, 0x5D, 0x00, 0x26, 0x1B, 0xCA, 0x46, 0x67, 0x5A, 0xF2, 0x77, 0xB8, 0x7D, 0x86, 0xD8, 0x41, 0xDB, 0x05, 0x35, 0xCD, 0x83, 0xA5, 0x7C, 0x12, 0xA5, 0x05, 0xDB, 0x90, 0xBD, 0x2F, 0x14, 0xD3, 0x71, 0x72, 0x96, 0xA8, 0x8A, 0x7D, 0x84, 0x56, 0x71, 0x8D, 0x6A, 0x22, 0x98, 0xAB, 0x9E, 0x3D, 0x90, 0x80, 0x2D, 0xC7, 0x5E, 0x0C, 0x12, 0x52, 0xD3, 0x3F, 0x07, 0x08, 0x7B, 0x1C, 0xA4, 0x77, 0xF3, 0x13, 0xB8, 0x17, 0xC0, 0xEE, 0x91, 0x81, 0x39, 0xB3, 0x87, 0xF0, 0xFF, 0x00, 0xB3, 0x6A, 0x52, 0x41, 0xED, 0x2E, 0xB0, 0xF2, 0x64, 0x97, 0xA4, 0x9A, 0x9E, 0x63, 0xA1, 0xAE, 0x19, 0x74, 0x0D, 0xA9, 0xD5, 0x5B, 0x6C, 0xEE, 0xB1, 0xE0, 0x2C, 0xDC, 0x61, 0xDC, 0xCB, 0x9D, 0x86, 0xCF, 0xE1, 0xDC, 0x0A, 0x7A, 0x81, 0x14, 0x5F, 0xD0, 0x40, 0xC8, 0x7E, 0x0D, 0x97, 0x44, 0xCE, 0xB5, 0xC2, 0xFC, 0x2C, 0x59, 0x08, 0xBF, 0x03, 0x80, 0xDC, 0xD7, 0x44, 0x8E, 0xB3, 0xD4, 0x2D, 0xDE, 0xE5, 0x16, 0x21, 0x6E, 0x47, 0x82, 0xAC, 0x08, 0x59, 0xD8, 0xE4, 0x66, 0x29, 0x61, 0xD5, 0xD1, 0xFA, 0x49, 0x63, 0x90, 0x11, 0x3E, 0x20, 0xD0, 0xA9, 0xE2, 0xD5, 0x14, 0x81, 0xD9, 0x23, 0xD0, 0x8F, 0x43, 0xAE, 0x45, 0x55, 0x36, 0x69, 0xAA, 0x00, 0xC0, 0x00, 0xE5, 0x00, 0xAD, 0x0B, 0x00, 0x8C, 0xF1, 0x9D, 0x40, 0x2B, 0xD0, 0x7D, 0x1D, 0x99, 0xEE, 0xE4, 0xDC, 0x63, 0x74, 0x64, 0x46, 0xA4, 0xA0, 0x4A, 0x64, 0x65, 0xB2, 0xF6, 0x4E, 0xC1, 0xC8, 0x68, 0x9F, 0x27, 0x54, 0xAD, 0xBB, 0xA6, 0x34, 0x3C, 0x77, 0xEC, 0x0F, 0x2E, 0x1B, 0x8E, 0x42, 0x27, 0xE5, 0x68, 0xBF, 0x60, 0xF4, 0x0B, 0x3A, 0xF0, 0x9B, 0x31, 0xEB, 0xDF, 0x3F, 0xD8, 0xAF, 0xA5, 0x55, 0x92, 0x46, 0x05, 0x58, 0x22, 0x09, 0x8F, 0xA8, 0x60, 0x08, 0x0B, 0xA3, 0xE9, 0x3E, 0xBC, 0xB4, 0x16, 0xDB, 0xC7, 0xA3, 0xA2, 0xC0, 0x16, 0xD5, 0x14, 0xA7, 0x22, 0xE8, 0x2F, 0xE8, 0xB4, 0xD0, 0x77, 0x17, 0xC5, 0x8B, 0xE4, 0xF2, 0xBB, 0x6B, 0xD6, 0xEF, 0x9A, 0x81, 0x34, 0x4E, 0x1D, 0xDC, 0xEC, 0x36, 0xE6, 0x44, 0x72, 0xBF, 0x29, 0xB5, 0x3C, 0x05, 0x31, 0x60, 0x66, 0xBA, 0x2C, 0x03, 0x0F, 0xD6, 0x47, 0xC6, 0x7D, 0x85, 0xD4, 0xC5, 0x5E, 0x4E, 0x57, 0x73, 0xC3, 0x41, 0x69, 0xBE, 0x0D, 0x8C, 0x9C, 0xB5, 0x15, 0xA9, 0xE7, 0xD2, 0x78, 0x51, 0x4B, 0xD5, 0x29, 0xD0, 0xF9, 0x35, 0x1A, 0xC5, 0x5D, 0xF4, 0x8C, 0x7A, 0x70, 0xD5, 0x5E, 0xA8, 0x31, 0x57, 0x80, 0xC8, 0xA5, 0xD8, 0xE0, 0x00, 0x00, 0x00, 0xFB, 0x47, 0x48, 0xDB, 0x00, 0x01, 0x82, 0x03, 0xC9, 0x03, 0x00, 0x00, 0x0B, 0x04, 0x8E, 0xDE, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_lorem_ipsum.bytes()); } TEST_CASE(xz_utils_good_1_lzma2_2) { // "good-1-lzma2-2.xz has two LZMA2 chunks, of which the second resets // the state without specifying new properties." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0xE0, 0x00, 0xE2, 0x00, 0xB6, 0x5D, 0x00, 0x26, 0x1B, 0xCA, 0x46, 0x67, 0x5A, 0xF2, 0x77, 0xB8, 0x7D, 0x86, 0xD8, 0x41, 0xDB, 0x05, 0x35, 0xCD, 0x83, 0xA5, 0x7C, 0x12, 0xA5, 0x05, 0xDB, 0x90, 0xBD, 0x2F, 0x14, 0xD3, 0x71, 0x72, 0x96, 0xA8, 0x8A, 0x7D, 0x84, 0x56, 0x71, 0x8D, 0x6A, 0x22, 0x98, 0xAB, 0x9E, 0x3D, 0x90, 0x80, 0x2D, 0xC7, 0x5E, 0x0C, 0x12, 0x52, 0xD3, 0x3F, 0x07, 0x08, 0x7B, 0x1C, 0xA4, 0x77, 0xF3, 0x13, 0xB8, 0x17, 0xC0, 0xEE, 0x91, 0x81, 0x39, 0xB3, 0x87, 0xF0, 0xFF, 0x00, 0xB3, 0x6A, 0x52, 0x41, 0xED, 0x2E, 0xB0, 0xF2, 0x64, 0x97, 0xA4, 0x9A, 0x9E, 0x63, 0xA1, 0xAE, 0x19, 0x74, 0x0D, 0xA9, 0xD5, 0x5B, 0x6C, 0xEE, 0xB1, 0xE0, 0x2C, 0xDC, 0x61, 0xDC, 0xCB, 0x9D, 0x86, 0xCF, 0xE1, 0xDC, 0x0A, 0x7A, 0x81, 0x14, 0x5F, 0xD0, 0x40, 0xC8, 0x7E, 0x0D, 0x97, 0x44, 0xCE, 0xB5, 0xC2, 0xFC, 0x2C, 0x59, 0x08, 0xBF, 0x03, 0x80, 0xDC, 0xD7, 0x44, 0x8E, 0xB3, 0xD4, 0x2D, 0xDE, 0xE5, 0x16, 0x21, 0x6E, 0x47, 0x82, 0xAC, 0x08, 0x59, 0xD8, 0xE4, 0x66, 0x29, 0x61, 0xD5, 0xD1, 0xFA, 0x49, 0x63, 0x90, 0x11, 0x3E, 0x20, 0xD0, 0xA9, 0xE2, 0xD5, 0x14, 0x81, 0xD9, 0x23, 0xD0, 0x8F, 0x43, 0xAE, 0x45, 0x55, 0x36, 0x69, 0xAA, 0x00, 0xA0, 0x00, 0xE5, 0x00, 0xAF, 0x00, 0x8C, 0xF1, 0x9D, 0x40, 0x7D, 0x82, 0x4F, 0x24, 0x72, 0x14, 0xF1, 0x9D, 0x84, 0xCB, 0x5A, 0x32, 0x6C, 0x97, 0x6A, 0x40, 0x83, 0x8B, 0xF0, 0xAF, 0x31, 0xC2, 0xB4, 0x65, 0x6F, 0x89, 0xFD, 0xFB, 0xD8, 0x8B, 0x54, 0x41, 0x82, 0x16, 0x54, 0x12, 0xD1, 0x4D, 0xD5, 0x86, 0xC5, 0xC0, 0x5A, 0xFA, 0x49, 0x63, 0x91, 0x11, 0xFE, 0xFF, 0xF5, 0x8F, 0x14, 0x02, 0x85, 0x61, 0x79, 0x38, 0x4A, 0x4B, 0x4F, 0x41, 0x63, 0xF8, 0x87, 0x2F, 0x2C, 0xE6, 0xE2, 0xE9, 0x31, 0x8F, 0x8B, 0x14, 0xD3, 0xA1, 0x7E, 0x81, 0xE8, 0x55, 0x02, 0xEF, 0x21, 0x31, 0xA2, 0x7B, 0x05, 0xCC, 0x1F, 0xA4, 0x60, 0xE7, 0x81, 0xAA, 0xA7, 0xD9, 0x78, 0x82, 0xE6, 0x18, 0xB2, 0xAB, 0x1C, 0xAA, 0x19, 0x2F, 0xC2, 0x87, 0x14, 0xC5, 0xD9, 0xCB, 0x3F, 0xD0, 0x18, 0xA6, 0xCD, 0x2A, 0x4B, 0x5D, 0xA8, 0xC7, 0x5F, 0x01, 0x67, 0x28, 0x4C, 0x2C, 0xE4, 0xCC, 0xD5, 0x52, 0x9E, 0x93, 0x02, 0x7E, 0x10, 0x5D, 0xF5, 0x03, 0xB1, 0x98, 0x2F, 0x26, 0xED, 0x86, 0x7B, 0x56, 0x7F, 0x13, 0x79, 0x58, 0x8F, 0x44, 0x10, 0xD9, 0xD9, 0x0F, 0x96, 0xE9, 0x3B, 0xBF, 0xB5, 0xB8, 0xDA, 0x2B, 0xE1, 0xD6, 0x81, 0xF1, 0xC9, 0x00, 0x00, 0xFB, 0x47, 0x48, 0xDB, 0x00, 0x01, 0x83, 0x03, 0xC9, 0x03, 0x00, 0x00, 0xAE, 0xD7, 0xD2, 0x15, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_lorem_ipsum.bytes()); } TEST_CASE(xz_utils_good_1_lzma2_3) { // "good-1-lzma2-3.xz has two LZMA2 chunks, of which the first is // uncompressed and the second is LZMA. The first chunk resets dictionary // and the second sets new properties." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x34, 0x4C, 0x6F, 0x72, 0x65, 0x6D, 0x20, 0x69, 0x70, 0x73, 0x75, 0x6D, 0x20, 0x64, 0x6F, 0x6C, 0x6F, 0x72, 0x20, 0x73, 0x69, 0x74, 0x20, 0x61, 0x6D, 0x65, 0x74, 0x2C, 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x65, 0x63, 0x74, 0x65, 0x74, 0x75, 0x72, 0x20, 0x61, 0x64, 0x69, 0x70, 0x69, 0x73, 0x69, 0x63, 0x69, 0x6E, 0x67, 0x20, 0x0A, 0xC0, 0x01, 0x93, 0x01, 0x24, 0x5D, 0x00, 0x32, 0x9B, 0x09, 0x6C, 0x54, 0xD7, 0x2E, 0x95, 0x6C, 0xF9, 0xF7, 0x37, 0xD5, 0x1C, 0xE2, 0x46, 0x02, 0x82, 0x75, 0xFB, 0x49, 0x76, 0x8D, 0x73, 0x53, 0xB6, 0xFD, 0x6D, 0xDB, 0xCA, 0xDB, 0xD9, 0x44, 0x0B, 0xB1, 0x2E, 0xBE, 0x13, 0xB6, 0xBA, 0xA8, 0xE2, 0xF3, 0xED, 0x75, 0x54, 0xDC, 0x41, 0x20, 0xCC, 0xBF, 0x36, 0x5B, 0x20, 0x99, 0x5D, 0x0F, 0x21, 0xA1, 0x06, 0xA3, 0x96, 0x2D, 0xB7, 0x97, 0x9C, 0xF0, 0x7B, 0xFE, 0xE2, 0x12, 0x8C, 0x2D, 0x51, 0xF0, 0xDB, 0x76, 0x77, 0x7D, 0xA4, 0x7B, 0xD3, 0x95, 0xE9, 0xFB, 0x05, 0xE6, 0xF5, 0x97, 0x8F, 0x62, 0xE9, 0xDB, 0x30, 0xBB, 0xB4, 0x70, 0x3D, 0x16, 0x78, 0x03, 0x77, 0x3A, 0x8B, 0x7A, 0xD5, 0xB8, 0xF8, 0x4A, 0x27, 0x25, 0xF5, 0x8E, 0xAA, 0x24, 0x14, 0xA6, 0x29, 0x28, 0x6B, 0x2F, 0x73, 0xE0, 0xA1, 0x71, 0xB4, 0x7B, 0xA4, 0x80, 0x50, 0x40, 0xCA, 0xEF, 0xDB, 0xB4, 0x95, 0xFD, 0xBB, 0xC1, 0x8C, 0x8E, 0x60, 0x97, 0xDB, 0xCB, 0x7F, 0x21, 0xED, 0xC0, 0x10, 0x71, 0x1A, 0x7D, 0xCB, 0xCD, 0x09, 0xD0, 0xD9, 0xFF, 0x6D, 0x80, 0xC0, 0x67, 0x7D, 0x3F, 0xC6, 0x94, 0xCF, 0x5B, 0xDD, 0x51, 0x11, 0xD1, 0xCB, 0xD4, 0x20, 0xD7, 0x2B, 0x84, 0x4E, 0xA8, 0x45, 0xBB, 0x42, 0x78, 0x1A, 0x68, 0x40, 0x5F, 0x24, 0x5E, 0x89, 0x3A, 0x36, 0x7D, 0xDB, 0x98, 0x28, 0xCC, 0xF9, 0x83, 0xEC, 0x32, 0x06, 0x31, 0x47, 0x47, 0x3B, 0x6C, 0x1C, 0xF4, 0x62, 0x34, 0x40, 0xB3, 0x28, 0xBB, 0x54, 0x36, 0xDD, 0x7A, 0x0E, 0x1C, 0x36, 0x25, 0x38, 0x58, 0x06, 0xF8, 0x15, 0xA3, 0xCE, 0x18, 0xC8, 0xFD, 0x96, 0x1E, 0x69, 0x29, 0x03, 0xC3, 0xBD, 0x27, 0xF3, 0xE7, 0x8F, 0xDB, 0x73, 0xB4, 0x2B, 0x4F, 0x38, 0x58, 0x24, 0xBF, 0x83, 0x14, 0x39, 0x7E, 0x73, 0xEE, 0xFE, 0xCF, 0xCA, 0xBD, 0xF3, 0x21, 0x6A, 0x28, 0x80, 0xC8, 0x8E, 0x5D, 0x81, 0xC7, 0xBC, 0x17, 0xD0, 0x2C, 0x93, 0xB5, 0x08, 0x95, 0xBA, 0x0E, 0x92, 0x82, 0x66, 0xAE, 0xFF, 0xB8, 0x03, 0x00, 0xFB, 0x47, 0x48, 0xDB, 0x00, 0x01, 0xF4, 0x02, 0xC9, 0x03, 0x00, 0x00, 0x67, 0xC3, 0x95, 0x3E, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_lorem_ipsum.bytes()); } TEST_CASE(xz_utils_good_1_lzma2_4) { // "good-1-lzma2-4.xz has three LZMA2 chunks: First is LZMA, second is // uncompressed with dictionary reset, and third is LZMA with new // properties but without dictionary reset." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x04, 0xE6, 0xD6, 0xB4, 0x46, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0xE0, 0x00, 0xBB, 0x00, 0xA1, 0x5D, 0x00, 0x26, 0x1B, 0xCA, 0x46, 0x67, 0x5A, 0xF2, 0x77, 0xB8, 0x7D, 0x86, 0xD8, 0x41, 0xDB, 0x05, 0x35, 0xCD, 0x83, 0xA5, 0x7C, 0x12, 0xA5, 0x05, 0xDB, 0x90, 0xBD, 0x2F, 0x14, 0xD3, 0x71, 0x72, 0x96, 0xA8, 0x8A, 0x7D, 0x84, 0x56, 0x71, 0x8D, 0x6A, 0x22, 0x98, 0xAB, 0x9E, 0x3D, 0x90, 0x80, 0x2D, 0xC7, 0x5E, 0x0C, 0x12, 0x52, 0xD3, 0x3F, 0x07, 0x08, 0x7B, 0x1C, 0xA4, 0x77, 0xF3, 0x13, 0xB8, 0x17, 0xC0, 0xEE, 0x91, 0x73, 0xCA, 0xBC, 0xCF, 0xEB, 0x34, 0x66, 0xAC, 0x48, 0x9B, 0x69, 0xD9, 0x93, 0x07, 0xAE, 0xCE, 0x50, 0xAF, 0x68, 0x09, 0x2F, 0x5B, 0x88, 0x1F, 0xC2, 0x08, 0xA2, 0x2C, 0x58, 0x45, 0xB0, 0xFF, 0x62, 0x09, 0xEB, 0xEE, 0xDB, 0x63, 0x4F, 0x6F, 0xE0, 0xF3, 0x1F, 0xCF, 0x12, 0x37, 0x98, 0x96, 0x4E, 0xF6, 0xF2, 0xB2, 0xFB, 0x6E, 0xAF, 0x44, 0x02, 0xE2, 0x22, 0xDE, 0xD5, 0xE6, 0x34, 0x97, 0x39, 0xA3, 0x45, 0x2F, 0xAE, 0x99, 0x2F, 0x79, 0x69, 0x8F, 0xE9, 0x37, 0x89, 0x48, 0xFE, 0xCC, 0x7E, 0xEA, 0xA9, 0x28, 0xAD, 0xC3, 0xE6, 0xDC, 0xB9, 0xDA, 0xAA, 0x16, 0x7E, 0x01, 0x00, 0x26, 0x6C, 0x61, 0x62, 0x6F, 0x72, 0x69, 0x73, 0x20, 0x6E, 0x69, 0x73, 0x69, 0x20, 0x75, 0x74, 0x20, 0x61, 0x6C, 0x69, 0x71, 0x75, 0x69, 0x70, 0x20, 0x65, 0x78, 0x20, 0x65, 0x61, 0x20, 0x63, 0x6F, 0x6D, 0x6D, 0x6F, 0x64, 0x6F, 0x20, 0x0A, 0xC0, 0x00, 0xE5, 0x00, 0xBD, 0x5D, 0x00, 0x31, 0x9B, 0xCA, 0x19, 0xC5, 0x54, 0xEC, 0xB6, 0x54, 0xE7, 0xB1, 0x7D, 0xC4, 0x57, 0x9E, 0x6C, 0x89, 0xAD, 0x4A, 0x6D, 0x16, 0xD8, 0x3C, 0x05, 0x94, 0x10, 0x16, 0x99, 0x38, 0x21, 0xA3, 0xB9, 0xC5, 0x80, 0xFF, 0xFC, 0xEE, 0xD4, 0xD5, 0x3F, 0xDD, 0x8C, 0xD7, 0x3D, 0x8F, 0x76, 0xEC, 0x88, 0xAA, 0x32, 0xAB, 0x65, 0xD4, 0x38, 0xEF, 0xF7, 0xF9, 0x8A, 0xBF, 0xF7, 0xF8, 0xA5, 0x56, 0xD7, 0x6D, 0xD7, 0x3F, 0x85, 0x0B, 0x9E, 0x3F, 0xE2, 0x47, 0x68, 0x22, 0x08, 0x05, 0x35, 0xB8, 0x41, 0x72, 0xF9, 0xDB, 0xBE, 0xB7, 0x8E, 0x86, 0xBF, 0x43, 0x4B, 0x8E, 0x0D, 0x43, 0x2F, 0x41, 0x69, 0xDF, 0x61, 0x0C, 0xC4, 0xE8, 0x37, 0x08, 0x4A, 0xDE, 0xC2, 0x76, 0x16, 0xB8, 0x48, 0x4E, 0x9E, 0xB9, 0x53, 0x50, 0x1F, 0x33, 0x83, 0xE8, 0x29, 0xA0, 0x67, 0xC8, 0x66, 0x3A, 0x7F, 0x22, 0x12, 0x62, 0xFB, 0x47, 0xE4, 0xBC, 0xF4, 0x51, 0x0F, 0x15, 0x88, 0x49, 0xD8, 0xCA, 0x0B, 0x25, 0x8B, 0x5E, 0xE8, 0xDA, 0xFD, 0x38, 0xC0, 0xCE, 0x4C, 0x73, 0x1B, 0xFF, 0xD0, 0x9B, 0xE8, 0x4C, 0xB7, 0x13, 0xF8, 0x37, 0x99, 0xE2, 0xDA, 0x9C, 0x2F, 0xB5, 0xEA, 0xB8, 0xA5, 0x8D, 0xEA, 0x57, 0x82, 0x9B, 0x25, 0xCA, 0xFB, 0xF6, 0x88, 0x0A, 0x9B, 0xDF, 0x41, 0x03, 0x6E, 0x00, 0x00, 0x00, 0xB2, 0x07, 0x44, 0xE9, 0x17, 0x33, 0x4B, 0x84, 0x00, 0x01, 0xAB, 0x03, 0xC9, 0x03, 0x00, 0x00, 0xF5, 0x50, 0x2D, 0xFE, 0xB1, 0xC4, 0x67, 0xFB, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_lorem_ipsum.bytes()); } TEST_CASE(xz_utils_good_1_lzma2_5) { // "good-1-lzma2-4.xz has three LZMA2 chunks: First is LZMA, second is // uncompressed with dictionary reset, and third is LZMA with new // properties but without dictionary reset." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x10, 0x00, 0x00, 0x00, 0xA8, 0x70, 0x8E, 0x86, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x3B, 0x96, 0x5F, 0x73, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.size(), 0ul); } TEST_CASE(xz_utils_good_1_sparc_lzma2) { // "good-1-sparc-lzma2.xz uses the SPARC filter and LZMA2. The // uncompressed file is compress_prepared_bcj_sparc found from the tests // directory." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x04, 0xE6, 0xD6, 0xB4, 0x46, 0x02, 0x01, 0x09, 0x00, 0x21, 0x01, 0x08, 0x00, 0x0C, 0xAA, 0xEA, 0x77, 0xE0, 0x04, 0xD7, 0x02, 0x22, 0x5D, 0x00, 0x3F, 0x91, 0x45, 0x84, 0x68, 0x34, 0x8A, 0x09, 0x0A, 0x41, 0x50, 0x57, 0x98, 0xF3, 0xBD, 0x43, 0xCD, 0x26, 0xE9, 0xC6, 0xC9, 0xED, 0x84, 0x68, 0x5E, 0xA7, 0xDD, 0xE8, 0xA0, 0xA8, 0x77, 0x31, 0xD2, 0xA0, 0x05, 0xC6, 0x90, 0x2C, 0x60, 0xDB, 0x04, 0x0C, 0x2E, 0xCC, 0xED, 0x09, 0x92, 0xC5, 0x8B, 0xA2, 0x23, 0x64, 0x7D, 0x17, 0xF8, 0xE1, 0xC7, 0x24, 0x0B, 0xC2, 0x2A, 0xDB, 0x03, 0x4F, 0x3C, 0x4E, 0xBC, 0x89, 0x17, 0xD7, 0xAF, 0x79, 0x88, 0x85, 0x36, 0x8C, 0x6E, 0xD5, 0x3C, 0x34, 0x6A, 0x29, 0xA0, 0x45, 0x27, 0x85, 0x43, 0x52, 0xAF, 0x51, 0x9E, 0x4B, 0x5E, 0x9E, 0x34, 0xC1, 0xFF, 0x8E, 0xC1, 0xBD, 0xE1, 0x0C, 0xD6, 0x21, 0x50, 0x5E, 0x14, 0x3B, 0x29, 0x54, 0x65, 0x28, 0x90, 0x72, 0x4E, 0x2D, 0x65, 0x51, 0x35, 0x90, 0x25, 0x76, 0xB7, 0x61, 0x8A, 0x9F, 0xF0, 0x14, 0x75, 0x39, 0xAA, 0xAE, 0x75, 0x17, 0xAB, 0x29, 0xDB, 0x36, 0xF6, 0xAE, 0xC6, 0x02, 0x3A, 0x3A, 0x93, 0x05, 0x6C, 0x85, 0xA3, 0x8E, 0x55, 0xF0, 0x06, 0xC3, 0x37, 0x36, 0x90, 0xBB, 0x9B, 0x9C, 0x31, 0x01, 0x6B, 0xDC, 0x9E, 0xFA, 0x6F, 0x2E, 0xF8, 0xA1, 0xC4, 0xCA, 0x6E, 0x27, 0x7C, 0x74, 0x1F, 0x28, 0xE8, 0x7A, 0x76, 0x3F, 0xC3, 0x92, 0x24, 0x21, 0x8E, 0xD3, 0x0B, 0xC2, 0x13, 0xF5, 0x12, 0xCE, 0x3B, 0x1A, 0x19, 0x57, 0x95, 0xFA, 0x9D, 0x3F, 0xDE, 0x16, 0xD2, 0x78, 0x10, 0x01, 0x1A, 0x42, 0x11, 0xD9, 0x7B, 0xC0, 0x8E, 0x2C, 0x78, 0x9F, 0xCB, 0x43, 0xAF, 0xEE, 0x56, 0xA3, 0xAE, 0x03, 0x70, 0xB7, 0x13, 0xB3, 0xE5, 0x31, 0xDB, 0x63, 0xDA, 0x65, 0xFA, 0x1F, 0xB6, 0x74, 0xE1, 0xF7, 0xC4, 0x93, 0xA5, 0x03, 0xB7, 0xFC, 0x93, 0x31, 0x39, 0xA1, 0xFB, 0x82, 0xED, 0x6F, 0xC0, 0xC2, 0xDA, 0xDF, 0x5D, 0x45, 0x54, 0x00, 0x5F, 0x4E, 0x35, 0xB0, 0xDE, 0xEE, 0x47, 0x37, 0x0A, 0x66, 0x1C, 0x3C, 0x69, 0xEF, 0xD1, 0x7D, 0x39, 0x75, 0x45, 0xC4, 0x49, 0x5A, 0x86, 0xA2, 0x7E, 0x45, 0xB9, 0x8E, 0x39, 0x1D, 0x47, 0xA0, 0x5B, 0x3A, 0xD8, 0x24, 0x97, 0xE8, 0x17, 0x80, 0x81, 0xCD, 0xE6, 0xC8, 0x42, 0x47, 0x65, 0x50, 0x33, 0xE4, 0x6B, 0x99, 0xA7, 0xA4, 0x33, 0x0D, 0xC3, 0x0E, 0x8E, 0x18, 0xEE, 0x06, 0x85, 0xD1, 0xD3, 0xCF, 0x6E, 0xCB, 0x8F, 0x67, 0x07, 0x84, 0x08, 0xF3, 0xBB, 0xA1, 0x48, 0xDE, 0x81, 0x79, 0xBA, 0xFA, 0x1B, 0x36, 0x3E, 0xFA, 0x7E, 0x53, 0xB7, 0xDD, 0x9C, 0xF0, 0xB6, 0x57, 0x93, 0x8E, 0x31, 0xAF, 0x52, 0xEC, 0xD6, 0x1F, 0x42, 0xC6, 0x77, 0x5C, 0x23, 0x8A, 0x2C, 0xAF, 0xDF, 0x18, 0x9A, 0xAB, 0x63, 0x9E, 0x30, 0x32, 0xF1, 0xD1, 0x22, 0x7F, 0xAE, 0xF1, 0x5A, 0xCD, 0xEC, 0x15, 0x55, 0x1D, 0x31, 0xB1, 0x7A, 0x59, 0x72, 0xF8, 0x38, 0x9E, 0xE2, 0x50, 0x24, 0x2E, 0x98, 0x83, 0x67, 0x9C, 0xF0, 0xB6, 0x5F, 0x1B, 0x4F, 0x04, 0xA8, 0x83, 0xF6, 0x87, 0x64, 0x5B, 0x2E, 0xB7, 0xC5, 0x16, 0x66, 0xDF, 0xA1, 0xE5, 0xD0, 0x89, 0x53, 0xEA, 0x46, 0x2C, 0xB8, 0x2A, 0xBE, 0x71, 0x16, 0x93, 0x41, 0x20, 0x68, 0x68, 0x0A, 0x61, 0x39, 0x4A, 0xD4, 0xB7, 0x28, 0x37, 0x06, 0x7D, 0x18, 0x83, 0x30, 0x7E, 0xD7, 0x6C, 0x1E, 0xA6, 0xD5, 0xE5, 0x40, 0xC0, 0x96, 0xAC, 0x8A, 0xCB, 0x6E, 0xCD, 0x63, 0x76, 0xDC, 0xCC, 0x94, 0x25, 0x80, 0x34, 0xC2, 0xDB, 0x5E, 0x78, 0x76, 0x6F, 0x10, 0xEE, 0x66, 0x5D, 0x85, 0x4F, 0x1E, 0x83, 0x62, 0x70, 0x72, 0x6F, 0x88, 0x9B, 0xF7, 0xF3, 0x60, 0xE0, 0xA0, 0xD3, 0xF4, 0x22, 0xE9, 0xEF, 0xD1, 0x22, 0xA8, 0x83, 0x09, 0x9B, 0x13, 0x53, 0xAC, 0x12, 0xEA, 0x63, 0xCE, 0xC8, 0xA8, 0x3A, 0x4F, 0xF1, 0xC9, 0x58, 0xDA, 0x69, 0x02, 0xAF, 0x65, 0x7C, 0x57, 0xF2, 0x62, 0xEE, 0x7F, 0x71, 0x56, 0x00, 0x00, 0x00, 0x00, 0xF7, 0xBD, 0x07, 0x0A, 0x2D, 0x3A, 0x72, 0xFA, 0x00, 0x01, 0xBE, 0x04, 0xD8, 0x09, 0x00, 0x00, 0xE1, 0xAA, 0x24, 0xFA, 0xB1, 0xC4, 0x67, 0xFB, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: This uses the currently unimplemented SPARC branch/call/jump filter. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_good_1_x86_lzma2) { // "good-1-x86-lzma2.xz uses the x86 filter (BCJ) and LZMA2. The // uncompressed file is compress_prepared_bcj_x86 found from the tests // directory." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x04, 0xE6, 0xD6, 0xB4, 0x46, 0x02, 0x01, 0x04, 0x00, 0x21, 0x01, 0x08, 0x00, 0xD2, 0xB9, 0x74, 0xCB, 0xE0, 0x05, 0x6B, 0x02, 0x8A, 0x5D, 0x00, 0x3F, 0x91, 0x45, 0x84, 0x68, 0x3B, 0xDE, 0xDE, 0xA8, 0x4B, 0x03, 0xD8, 0x35, 0x53, 0xA4, 0x91, 0x73, 0xA3, 0xE5, 0x1B, 0x1E, 0x5B, 0x1D, 0x4A, 0xF1, 0x06, 0xC1, 0xAE, 0x79, 0xEA, 0x45, 0x62, 0x76, 0x0C, 0x29, 0xCD, 0x4B, 0x9F, 0x6E, 0xCD, 0x71, 0xB9, 0x15, 0xF0, 0x80, 0x58, 0xDE, 0x71, 0xF6, 0x38, 0x55, 0x95, 0xD1, 0xFB, 0x03, 0xF0, 0xA9, 0x04, 0x71, 0x86, 0xC5, 0xD6, 0x4B, 0xB7, 0x0F, 0xCE, 0x3C, 0x29, 0xA7, 0x05, 0x65, 0x35, 0xCF, 0x9D, 0xFF, 0x7A, 0x18, 0xCD, 0x09, 0x8B, 0xDD, 0xAA, 0x4E, 0xEB, 0xE8, 0x21, 0xF4, 0x3D, 0xDF, 0x57, 0x4F, 0xF6, 0x62, 0x96, 0x34, 0x36, 0x9C, 0xCB, 0x20, 0x48, 0x9F, 0x20, 0xEC, 0x87, 0xEE, 0x19, 0x4E, 0xCB, 0x01, 0x82, 0x21, 0x08, 0x75, 0xBB, 0x09, 0x4D, 0x83, 0xCB, 0xC4, 0x10, 0xC1, 0xDF, 0x6F, 0xE6, 0x6E, 0x29, 0x9A, 0x51, 0x84, 0x0B, 0x67, 0x34, 0x54, 0x4C, 0x0B, 0xDD, 0x5F, 0xBA, 0xE8, 0xBB, 0x23, 0x9E, 0x3E, 0x50, 0x3B, 0x34, 0x82, 0x66, 0x06, 0xDB, 0x21, 0x6A, 0x62, 0x5B, 0x5F, 0x10, 0xB6, 0x7A, 0x70, 0x85, 0xB4, 0x3E, 0x7E, 0x6D, 0x25, 0x7B, 0x7D, 0x48, 0x59, 0xCA, 0x94, 0xE9, 0xDB, 0xB6, 0x60, 0xE5, 0x89, 0x24, 0xBE, 0xC6, 0x32, 0xC5, 0x18, 0xF1, 0x56, 0x2F, 0x1F, 0x24, 0x30, 0xB7, 0x62, 0x0C, 0x4B, 0x98, 0xF5, 0x5A, 0xE7, 0xF8, 0x7A, 0x1E, 0x4A, 0x44, 0xC6, 0x14, 0x6E, 0x87, 0xD8, 0xCE, 0xE5, 0x0E, 0x33, 0x8B, 0x14, 0x6D, 0xD2, 0xD0, 0xF6, 0xD6, 0xAB, 0x68, 0x4B, 0xC8, 0x75, 0xE4, 0x95, 0xE7, 0x03, 0x69, 0x89, 0x3F, 0xB0, 0x07, 0xC0, 0x59, 0x4F, 0xEA, 0x26, 0x85, 0x36, 0x7A, 0x87, 0xC3, 0x87, 0x74, 0x0A, 0xB1, 0x77, 0xE5, 0x3F, 0xAD, 0xB1, 0xFF, 0x3B, 0xAC, 0xA4, 0x3D, 0x7C, 0xAC, 0xF7, 0xA6, 0xC5, 0xBC, 0xFE, 0x33, 0xF4, 0xB0, 0x26, 0xAF, 0xF1, 0x00, 0x57, 0xC8, 0x5F, 0x5A, 0xF5, 0xD6, 0xA7, 0x59, 0x4F, 0xA6, 0x5A, 0x3D, 0x69, 0xB1, 0xC1, 0x80, 0x39, 0x1B, 0x67, 0x86, 0x5E, 0xED, 0x78, 0x37, 0x06, 0x45, 0x0E, 0x85, 0xF3, 0x11, 0xC2, 0x71, 0x00, 0x92, 0xA4, 0x66, 0x1B, 0x1C, 0xDC, 0x6F, 0xC5, 0x58, 0xA7, 0xED, 0x8C, 0x6F, 0xCD, 0x4D, 0x97, 0xAE, 0xE6, 0xBE, 0x52, 0x5E, 0x9C, 0x5F, 0x1A, 0xDE, 0x06, 0x23, 0xDA, 0x1E, 0x06, 0x8D, 0x76, 0x6B, 0x33, 0x06, 0x6B, 0xEC, 0xA4, 0x34, 0xFD, 0xD0, 0xF6, 0x72, 0xCC, 0x05, 0x09, 0xDB, 0xD1, 0xDE, 0x06, 0xA4, 0xE4, 0x18, 0x34, 0xF3, 0x51, 0x2F, 0x5C, 0x98, 0x55, 0xAB, 0xCD, 0x08, 0x7B, 0x2F, 0x80, 0x9E, 0x8D, 0x49, 0xD9, 0xB7, 0xB8, 0x35, 0x94, 0xB5, 0xEC, 0x16, 0xAD, 0x3B, 0x1B, 0x7E, 0x9A, 0x2D, 0xA5, 0x84, 0x8C, 0xFC, 0xB3, 0x4D, 0x3F, 0x06, 0x53, 0x90, 0x7D, 0x53, 0x3E, 0x18, 0xD1, 0x65, 0xB0, 0x91, 0x93, 0x97, 0x57, 0x7C, 0x9E, 0xD3, 0xAE, 0xA9, 0x6D, 0x52, 0xD8, 0xCF, 0xE8, 0x7C, 0xF2, 0xC5, 0xB3, 0x9C, 0xF7, 0xFF, 0x55, 0xEF, 0x1B, 0x90, 0x5A, 0xE1, 0x03, 0xC2, 0x20, 0x87, 0x8C, 0x8E, 0xF1, 0x00, 0x7A, 0x0A, 0x46, 0xE2, 0x72, 0xA5, 0x27, 0xC0, 0x6F, 0x87, 0xCE, 0x37, 0xBB, 0x3A, 0x5D, 0xD3, 0x9C, 0x4F, 0x71, 0x7C, 0xD3, 0xCE, 0xB1, 0xE3, 0xD3, 0x6E, 0x23, 0x67, 0x8D, 0xDB, 0xF6, 0x04, 0x66, 0xAA, 0x70, 0x5D, 0x73, 0xD0, 0x91, 0x22, 0x5A, 0xF9, 0xB4, 0x86, 0x2A, 0xA1, 0x1C, 0x04, 0xAE, 0xC5, 0xE5, 0x14, 0x05, 0x11, 0xF3, 0xCD, 0xBC, 0xFF, 0x4E, 0x15, 0x9F, 0x82, 0x51, 0x61, 0x1C, 0x6B, 0xBC, 0xAE, 0x79, 0x16, 0x38, 0x88, 0x2C, 0x96, 0x86, 0x98, 0x1D, 0xE4, 0x5B, 0x11, 0x3A, 0x31, 0x57, 0x1C, 0xE6, 0x96, 0xE8, 0xBB, 0xA1, 0x0A, 0xA3, 0xA4, 0xA9, 0xA0, 0x98, 0x33, 0x8C, 0xBD, 0x22, 0x38, 0x4D, 0x82, 0xA7, 0xBD, 0x81, 0x10, 0x75, 0x48, 0xF8, 0x85, 0x8A, 0xA7, 0xA0, 0x48, 0xF5, 0xA6, 0x0A, 0xF3, 0xB0, 0x5F, 0xEF, 0x51, 0x95, 0x68, 0x06, 0xEC, 0x08, 0x1A, 0xF6, 0xAB, 0xA5, 0x60, 0xC1, 0x25, 0x96, 0xD8, 0xD0, 0x39, 0x62, 0x08, 0xD8, 0xAD, 0x6E, 0x35, 0xD7, 0xC3, 0x34, 0x30, 0x6F, 0x54, 0x47, 0x8E, 0x9C, 0xE8, 0xF8, 0xEE, 0x3E, 0x1F, 0xF2, 0x04, 0xEB, 0xA3, 0xD8, 0x58, 0x85, 0xE2, 0x75, 0x88, 0x0E, 0x14, 0xDA, 0x9F, 0x66, 0x60, 0x7C, 0x9A, 0xF3, 0x70, 0x27, 0xA2, 0xAC, 0xC6, 0x9C, 0x0A, 0xE1, 0xAF, 0x9B, 0xB2, 0x70, 0x9E, 0x6D, 0x27, 0x17, 0x3C, 0x59, 0x96, 0x20, 0x4E, 0xBC, 0x02, 0xDF, 0x7B, 0x31, 0xD1, 0x0F, 0x96, 0x8E, 0x5A, 0xF9, 0xE5, 0x84, 0xA7, 0x00, 0x00, 0x00, 0xCC, 0xFE, 0xAF, 0xFF, 0x32, 0x1D, 0x43, 0xB0, 0x00, 0x01, 0xA6, 0x05, 0xEC, 0x0A, 0x00, 0x00, 0x08, 0xD2, 0xCE, 0x55, 0xB1, 0xC4, 0x67, 0xFB, 0x02, 0x00, 0x00, 0x00, 0x00, 0x04, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: This uses the currently unimplemented x86 branch/call/jump filter. (void)decompressor->read_until_eof(PAGE_SIZE); } TEST_CASE(xz_utils_good_2_lzma2) { // "good-2-lzma2.xz has one Stream with two Blocks with one uncompressed // LZMA2 chunk in each Block." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x00, 0x00, 0x00, 0x16, 0x35, 0x96, 0x31, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x00, 0xDD, 0xD1, 0xCA, 0x53, 0x00, 0x02, 0x1A, 0x06, 0x1B, 0x07, 0x00, 0x00, 0x06, 0xDC, 0xE7, 0x5D, 0x3E, 0x30, 0x0D, 0x8B, 0x02, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); auto buffer = TRY_OR_FAIL(decompressor->read_until_eof(PAGE_SIZE)); EXPECT_EQ(buffer.span(), xz_utils_hello_world.bytes()); } // The following test files are designated as "unsupported", which usually means that they test indicators // for not-yet-specified features or where they test files that are not explicitly wrong but that would fail // in the reference implementation due to self-imposed limits (i.e. filter ordering restrictions). TEST_CASE(xz_utils_unsupported_block_header) { // "unsupported-block_header.xz has a non-null byte in Header Padding, // which may indicate presence of a new unsupported field." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x01, 0x4E, 0x3F, 0x24, 0x64, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // 3.1.6. Header Padding: // "If any of the bytes are not null bytes, the decoder MUST // indicate an error. It is possible that there is a new field // present which the decoder is not aware of, and can thus parse // the Block Header incorrectly." // We test for failure in accordance with the specification. // In our in-tree setup of tests and implementation, changing this down the line is trivial. auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_unsupported_check) { // "unsupported-check.xz uses Check ID 0x02 which isn't supported by // the current version of the file format." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x02, 0xD3, 0x73, 0xD7, 0xAF, 0x02, 0x00, 0x21, 0x01, 0x08, 0x00, 0x00, 0x00, 0xD8, 0x0F, 0x23, 0x13, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x2A, 0x13, 0x90, 0x94, 0x01, 0x00, 0x00, 0x00, 0x00, 0x02, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // 2.1.1.2. Stream Flags: // "If an unsupported Check is used, the decoder SHOULD // indicate a warning or error." // We are throwing errors for unknown check IDs, so let's check for that. auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_unsupported_filter_flags_1) { // "unsupported-filter_flags-1.xz has unsupported Filter ID 0x7F." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x73, 0xDD, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // Behavior for unknown filter IDs is not specified at all, but we are throwing errors, so let's test for that. auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_unsupported_filter_flags_2) { // "unsupported-filter_flags-2.xz specifies only Delta filter in the // List of Filter Flags, but Delta isn't allowed as the last filter in // the chain. It could be a little more correct to detect this file as // corrupt instead of unsupported, but saying it is unsupported is // simpler in case of liblzma." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x00, 0x03, 0x01, 0xFF, 0x00, 0x00, 0x00, 0xFB, 0x85, 0xF6, 0x42, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // TODO: The delta filter is currently unimplemented. However, once it is implemented, we likely want to mirror the recommended behavior of the specification anyways. auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); } TEST_CASE(xz_utils_unsupported_filter_flags_3) { // "unsupported-filter_flags-3.xz specifies two LZMA2 filters in the // List of Filter Flags. LZMA2 is allowed only as the last filter in the // chain. It could be a little more correct to detect this file as // corrupt instead of unsupported, but saying it is unsupported is // simpler in case of liblzma." Array const compressed { 0xFD, 0x37, 0x7A, 0x58, 0x5A, 0x00, 0x00, 0x01, 0x69, 0x22, 0xDE, 0x36, 0x02, 0x01, 0x21, 0x01, 0x08, 0x21, 0x01, 0x08, 0xC8, 0x91, 0x1B, 0x9B, 0x01, 0x00, 0x05, 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x0A, 0x02, 0x00, 0x06, 0x57, 0x6F, 0x72, 0x6C, 0x64, 0x21, 0x0A, 0x00, 0x43, 0xA3, 0xA2, 0x15, 0x00, 0x01, 0x24, 0x0D, 0x30, 0x28, 0xDF, 0xAF, 0x90, 0x42, 0x99, 0x0D, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x59, 0x5A }; auto stream = MUST(try_make(compressed)); auto decompressor = MUST(Compress::XzDecompressor::create(move(stream))); // Similar to the recommended behavior of the specification, we reject LZMA2 filters if they aren't the last one. auto buffer_or_error = decompressor->read_until_eof(PAGE_SIZE); EXPECT(buffer_or_error.is_error()); }