Home | History | Annotate | Download | only in test
      1 import _compression
      2 from io import BytesIO, UnsupportedOperation, DEFAULT_BUFFER_SIZE
      3 import os
      4 import pathlib
      5 import pickle
      6 import random
      7 import unittest
      8 
      9 from test.support import (
     10     _4G, TESTFN, import_module, bigmemtest, run_unittest, unlink
     11 )
     12 
     13 lzma = import_module("lzma")
     14 from lzma import LZMACompressor, LZMADecompressor, LZMAError, LZMAFile
     15 
     16 
     17 class CompressorDecompressorTestCase(unittest.TestCase):
     18 
     19     # Test error cases.
     20 
     21     def test_simple_bad_args(self):
     22         self.assertRaises(TypeError, LZMACompressor, [])
     23         self.assertRaises(TypeError, LZMACompressor, format=3.45)
     24         self.assertRaises(TypeError, LZMACompressor, check="")
     25         self.assertRaises(TypeError, LZMACompressor, preset="asdf")
     26         self.assertRaises(TypeError, LZMACompressor, filters=3)
     27         # Can't specify FORMAT_AUTO when compressing.
     28         self.assertRaises(ValueError, LZMACompressor, format=lzma.FORMAT_AUTO)
     29         # Can't specify a preset and a custom filter chain at the same time.
     30         with self.assertRaises(ValueError):
     31             LZMACompressor(preset=7, filters=[{"id": lzma.FILTER_LZMA2}])
     32 
     33         self.assertRaises(TypeError, LZMADecompressor, ())
     34         self.assertRaises(TypeError, LZMADecompressor, memlimit=b"qw")
     35         with self.assertRaises(TypeError):
     36             LZMADecompressor(lzma.FORMAT_RAW, filters="zzz")
     37         # Cannot specify a memory limit with FILTER_RAW.
     38         with self.assertRaises(ValueError):
     39             LZMADecompressor(lzma.FORMAT_RAW, memlimit=0x1000000)
     40         # Can only specify a custom filter chain with FILTER_RAW.
     41         self.assertRaises(ValueError, LZMADecompressor, filters=FILTERS_RAW_1)
     42         with self.assertRaises(ValueError):
     43             LZMADecompressor(format=lzma.FORMAT_XZ, filters=FILTERS_RAW_1)
     44         with self.assertRaises(ValueError):
     45             LZMADecompressor(format=lzma.FORMAT_ALONE, filters=FILTERS_RAW_1)
     46 
     47         lzc = LZMACompressor()
     48         self.assertRaises(TypeError, lzc.compress)
     49         self.assertRaises(TypeError, lzc.compress, b"foo", b"bar")
     50         self.assertRaises(TypeError, lzc.flush, b"blah")
     51         empty = lzc.flush()
     52         self.assertRaises(ValueError, lzc.compress, b"quux")
     53         self.assertRaises(ValueError, lzc.flush)
     54 
     55         lzd = LZMADecompressor()
     56         self.assertRaises(TypeError, lzd.decompress)
     57         self.assertRaises(TypeError, lzd.decompress, b"foo", b"bar")
     58         lzd.decompress(empty)
     59         self.assertRaises(EOFError, lzd.decompress, b"quux")
     60 
     61     def test_bad_filter_spec(self):
     62         self.assertRaises(TypeError, LZMACompressor, filters=[b"wobsite"])
     63         self.assertRaises(ValueError, LZMACompressor, filters=[{"xyzzy": 3}])
     64         self.assertRaises(ValueError, LZMACompressor, filters=[{"id": 98765}])
     65         with self.assertRaises(ValueError):
     66             LZMACompressor(filters=[{"id": lzma.FILTER_LZMA2, "foo": 0}])
     67         with self.assertRaises(ValueError):
     68             LZMACompressor(filters=[{"id": lzma.FILTER_DELTA, "foo": 0}])
     69         with self.assertRaises(ValueError):
     70             LZMACompressor(filters=[{"id": lzma.FILTER_X86, "foo": 0}])
     71 
     72     def test_decompressor_after_eof(self):
     73         lzd = LZMADecompressor()
     74         lzd.decompress(COMPRESSED_XZ)
     75         self.assertRaises(EOFError, lzd.decompress, b"nyan")
     76 
     77     def test_decompressor_memlimit(self):
     78         lzd = LZMADecompressor(memlimit=1024)
     79         self.assertRaises(LZMAError, lzd.decompress, COMPRESSED_XZ)
     80 
     81         lzd = LZMADecompressor(lzma.FORMAT_XZ, memlimit=1024)
     82         self.assertRaises(LZMAError, lzd.decompress, COMPRESSED_XZ)
     83 
     84         lzd = LZMADecompressor(lzma.FORMAT_ALONE, memlimit=1024)
     85         self.assertRaises(LZMAError, lzd.decompress, COMPRESSED_ALONE)
     86 
     87     # Test LZMADecompressor on known-good input data.
     88 
     89     def _test_decompressor(self, lzd, data, check, unused_data=b""):
     90         self.assertFalse(lzd.eof)
     91         out = lzd.decompress(data)
     92         self.assertEqual(out, INPUT)
     93         self.assertEqual(lzd.check, check)
     94         self.assertTrue(lzd.eof)
     95         self.assertEqual(lzd.unused_data, unused_data)
     96 
     97     def test_decompressor_auto(self):
     98         lzd = LZMADecompressor()
     99         self._test_decompressor(lzd, COMPRESSED_XZ, lzma.CHECK_CRC64)
    100 
    101         lzd = LZMADecompressor()
    102         self._test_decompressor(lzd, COMPRESSED_ALONE, lzma.CHECK_NONE)
    103 
    104     def test_decompressor_xz(self):
    105         lzd = LZMADecompressor(lzma.FORMAT_XZ)
    106         self._test_decompressor(lzd, COMPRESSED_XZ, lzma.CHECK_CRC64)
    107 
    108     def test_decompressor_alone(self):
    109         lzd = LZMADecompressor(lzma.FORMAT_ALONE)
    110         self._test_decompressor(lzd, COMPRESSED_ALONE, lzma.CHECK_NONE)
    111 
    112     def test_decompressor_raw_1(self):
    113         lzd = LZMADecompressor(lzma.FORMAT_RAW, filters=FILTERS_RAW_1)
    114         self._test_decompressor(lzd, COMPRESSED_RAW_1, lzma.CHECK_NONE)
    115 
    116     def test_decompressor_raw_2(self):
    117         lzd = LZMADecompressor(lzma.FORMAT_RAW, filters=FILTERS_RAW_2)
    118         self._test_decompressor(lzd, COMPRESSED_RAW_2, lzma.CHECK_NONE)
    119 
    120     def test_decompressor_raw_3(self):
    121         lzd = LZMADecompressor(lzma.FORMAT_RAW, filters=FILTERS_RAW_3)
    122         self._test_decompressor(lzd, COMPRESSED_RAW_3, lzma.CHECK_NONE)
    123 
    124     def test_decompressor_raw_4(self):
    125         lzd = LZMADecompressor(lzma.FORMAT_RAW, filters=FILTERS_RAW_4)
    126         self._test_decompressor(lzd, COMPRESSED_RAW_4, lzma.CHECK_NONE)
    127 
    128     def test_decompressor_chunks(self):
    129         lzd = LZMADecompressor()
    130         out = []
    131         for i in range(0, len(COMPRESSED_XZ), 10):
    132             self.assertFalse(lzd.eof)
    133             out.append(lzd.decompress(COMPRESSED_XZ[i:i+10]))
    134         out = b"".join(out)
    135         self.assertEqual(out, INPUT)
    136         self.assertEqual(lzd.check, lzma.CHECK_CRC64)
    137         self.assertTrue(lzd.eof)
    138         self.assertEqual(lzd.unused_data, b"")
    139 
    140     def test_decompressor_chunks_empty(self):
    141         lzd = LZMADecompressor()
    142         out = []
    143         for i in range(0, len(COMPRESSED_XZ), 10):
    144             self.assertFalse(lzd.eof)
    145             out.append(lzd.decompress(b''))
    146             out.append(lzd.decompress(b''))
    147             out.append(lzd.decompress(b''))
    148             out.append(lzd.decompress(COMPRESSED_XZ[i:i+10]))
    149         out = b"".join(out)
    150         self.assertEqual(out, INPUT)
    151         self.assertEqual(lzd.check, lzma.CHECK_CRC64)
    152         self.assertTrue(lzd.eof)
    153         self.assertEqual(lzd.unused_data, b"")
    154 
    155     def test_decompressor_chunks_maxsize(self):
    156         lzd = LZMADecompressor()
    157         max_length = 100
    158         out = []
    159 
    160         # Feed first half the input
    161         len_ = len(COMPRESSED_XZ) // 2
    162         out.append(lzd.decompress(COMPRESSED_XZ[:len_],
    163                                   max_length=max_length))
    164         self.assertFalse(lzd.needs_input)
    165         self.assertEqual(len(out[-1]), max_length)
    166 
    167         # Retrieve more data without providing more input
    168         out.append(lzd.decompress(b'', max_length=max_length))
    169         self.assertFalse(lzd.needs_input)
    170         self.assertEqual(len(out[-1]), max_length)
    171 
    172         # Retrieve more data while providing more input
    173         out.append(lzd.decompress(COMPRESSED_XZ[len_:],
    174                                   max_length=max_length))
    175         self.assertLessEqual(len(out[-1]), max_length)
    176 
    177         # Retrieve remaining uncompressed data
    178         while not lzd.eof:
    179             out.append(lzd.decompress(b'', max_length=max_length))
    180             self.assertLessEqual(len(out[-1]), max_length)
    181 
    182         out = b"".join(out)
    183         self.assertEqual(out, INPUT)
    184         self.assertEqual(lzd.check, lzma.CHECK_CRC64)
    185         self.assertEqual(lzd.unused_data, b"")
    186 
    187     def test_decompressor_inputbuf_1(self):
    188         # Test reusing input buffer after moving existing
    189         # contents to beginning
    190         lzd = LZMADecompressor()
    191         out = []
    192 
    193         # Create input buffer and fill it
    194         self.assertEqual(lzd.decompress(COMPRESSED_XZ[:100],
    195                                         max_length=0), b'')
    196 
    197         # Retrieve some results, freeing capacity at beginning
    198         # of input buffer
    199         out.append(lzd.decompress(b'', 2))
    200 
    201         # Add more data that fits into input buffer after
    202         # moving existing data to beginning
    203         out.append(lzd.decompress(COMPRESSED_XZ[100:105], 15))
    204 
    205         # Decompress rest of data
    206         out.append(lzd.decompress(COMPRESSED_XZ[105:]))
    207         self.assertEqual(b''.join(out), INPUT)
    208 
    209     def test_decompressor_inputbuf_2(self):
    210         # Test reusing input buffer by appending data at the
    211         # end right away
    212         lzd = LZMADecompressor()
    213         out = []
    214 
    215         # Create input buffer and empty it
    216         self.assertEqual(lzd.decompress(COMPRESSED_XZ[:200],
    217                                         max_length=0), b'')
    218         out.append(lzd.decompress(b''))
    219 
    220         # Fill buffer with new data
    221         out.append(lzd.decompress(COMPRESSED_XZ[200:280], 2))
    222 
    223         # Append some more data, not enough to require resize
    224         out.append(lzd.decompress(COMPRESSED_XZ[280:300], 2))
    225 
    226         # Decompress rest of data
    227         out.append(lzd.decompress(COMPRESSED_XZ[300:]))
    228         self.assertEqual(b''.join(out), INPUT)
    229 
    230     def test_decompressor_inputbuf_3(self):
    231         # Test reusing input buffer after extending it
    232 
    233         lzd = LZMADecompressor()
    234         out = []
    235 
    236         # Create almost full input buffer
    237         out.append(lzd.decompress(COMPRESSED_XZ[:200], 5))
    238 
    239         # Add even more data to it, requiring resize
    240         out.append(lzd.decompress(COMPRESSED_XZ[200:300], 5))
    241 
    242         # Decompress rest of data
    243         out.append(lzd.decompress(COMPRESSED_XZ[300:]))
    244         self.assertEqual(b''.join(out), INPUT)
    245 
    246     def test_decompressor_unused_data(self):
    247         lzd = LZMADecompressor()
    248         extra = b"fooblibar"
    249         self._test_decompressor(lzd, COMPRESSED_XZ + extra, lzma.CHECK_CRC64,
    250                                 unused_data=extra)
    251 
    252     def test_decompressor_bad_input(self):
    253         lzd = LZMADecompressor()
    254         self.assertRaises(LZMAError, lzd.decompress, COMPRESSED_RAW_1)
    255 
    256         lzd = LZMADecompressor(lzma.FORMAT_XZ)
    257         self.assertRaises(LZMAError, lzd.decompress, COMPRESSED_ALONE)
    258 
    259         lzd = LZMADecompressor(lzma.FORMAT_ALONE)
    260         self.assertRaises(LZMAError, lzd.decompress, COMPRESSED_XZ)
    261 
    262         lzd = LZMADecompressor(lzma.FORMAT_RAW, filters=FILTERS_RAW_1)
    263         self.assertRaises(LZMAError, lzd.decompress, COMPRESSED_XZ)
    264 
    265     def test_decompressor_bug_28275(self):
    266         # Test coverage for Issue 28275
    267         lzd = LZMADecompressor()
    268         self.assertRaises(LZMAError, lzd.decompress, COMPRESSED_RAW_1)
    269         # Previously, a second call could crash due to internal inconsistency
    270         self.assertRaises(LZMAError, lzd.decompress, COMPRESSED_RAW_1)
    271 
    272     # Test that LZMACompressor->LZMADecompressor preserves the input data.
    273 
    274     def test_roundtrip_xz(self):
    275         lzc = LZMACompressor()
    276         cdata = lzc.compress(INPUT) + lzc.flush()
    277         lzd = LZMADecompressor()
    278         self._test_decompressor(lzd, cdata, lzma.CHECK_CRC64)
    279 
    280     def test_roundtrip_alone(self):
    281         lzc = LZMACompressor(lzma.FORMAT_ALONE)
    282         cdata = lzc.compress(INPUT) + lzc.flush()
    283         lzd = LZMADecompressor()
    284         self._test_decompressor(lzd, cdata, lzma.CHECK_NONE)
    285 
    286     def test_roundtrip_raw(self):
    287         lzc = LZMACompressor(lzma.FORMAT_RAW, filters=FILTERS_RAW_4)
    288         cdata = lzc.compress(INPUT) + lzc.flush()
    289         lzd = LZMADecompressor(lzma.FORMAT_RAW, filters=FILTERS_RAW_4)
    290         self._test_decompressor(lzd, cdata, lzma.CHECK_NONE)
    291 
    292     def test_roundtrip_raw_empty(self):
    293         lzc = LZMACompressor(lzma.FORMAT_RAW, filters=FILTERS_RAW_4)
    294         cdata = lzc.compress(INPUT)
    295         cdata += lzc.compress(b'')
    296         cdata += lzc.compress(b'')
    297         cdata += lzc.compress(b'')
    298         cdata += lzc.flush()
    299         lzd = LZMADecompressor(lzma.FORMAT_RAW, filters=FILTERS_RAW_4)
    300         self._test_decompressor(lzd, cdata, lzma.CHECK_NONE)
    301 
    302     def test_roundtrip_chunks(self):
    303         lzc = LZMACompressor()
    304         cdata = []
    305         for i in range(0, len(INPUT), 10):
    306             cdata.append(lzc.compress(INPUT[i:i+10]))
    307         cdata.append(lzc.flush())
    308         cdata = b"".join(cdata)
    309         lzd = LZMADecompressor()
    310         self._test_decompressor(lzd, cdata, lzma.CHECK_CRC64)
    311 
    312     def test_roundtrip_empty_chunks(self):
    313         lzc = LZMACompressor()
    314         cdata = []
    315         for i in range(0, len(INPUT), 10):
    316             cdata.append(lzc.compress(INPUT[i:i+10]))
    317             cdata.append(lzc.compress(b''))
    318             cdata.append(lzc.compress(b''))
    319             cdata.append(lzc.compress(b''))
    320         cdata.append(lzc.flush())
    321         cdata = b"".join(cdata)
    322         lzd = LZMADecompressor()
    323         self._test_decompressor(lzd, cdata, lzma.CHECK_CRC64)
    324 
    325     # LZMADecompressor intentionally does not handle concatenated streams.
    326 
    327     def test_decompressor_multistream(self):
    328         lzd = LZMADecompressor()
    329         self._test_decompressor(lzd, COMPRESSED_XZ + COMPRESSED_ALONE,
    330                                 lzma.CHECK_CRC64, unused_data=COMPRESSED_ALONE)
    331 
    332     # Test with inputs larger than 4GiB.
    333 
    334     @bigmemtest(size=_4G + 100, memuse=2)
    335     def test_compressor_bigmem(self, size):
    336         lzc = LZMACompressor()
    337         cdata = lzc.compress(b"x" * size) + lzc.flush()
    338         ddata = lzma.decompress(cdata)
    339         try:
    340             self.assertEqual(len(ddata), size)
    341             self.assertEqual(len(ddata.strip(b"x")), 0)
    342         finally:
    343             ddata = None
    344 
    345     @bigmemtest(size=_4G + 100, memuse=3)
    346     def test_decompressor_bigmem(self, size):
    347         lzd = LZMADecompressor()
    348         blocksize = 10 * 1024 * 1024
    349         block = random.getrandbits(blocksize * 8).to_bytes(blocksize, "little")
    350         try:
    351             input = block * (size // blocksize + 1)
    352             cdata = lzma.compress(input)
    353             ddata = lzd.decompress(cdata)
    354             self.assertEqual(ddata, input)
    355         finally:
    356             input = cdata = ddata = None
    357 
    358     # Pickling raises an exception; there's no way to serialize an lzma_stream.
    359 
    360     def test_pickle(self):
    361         for proto in range(pickle.HIGHEST_PROTOCOL + 1):
    362             with self.assertRaises(TypeError):
    363                 pickle.dumps(LZMACompressor(), proto)
    364             with self.assertRaises(TypeError):
    365                 pickle.dumps(LZMADecompressor(), proto)
    366 
    367 
    368 class CompressDecompressFunctionTestCase(unittest.TestCase):
    369 
    370     # Test error cases:
    371 
    372     def test_bad_args(self):
    373         self.assertRaises(TypeError, lzma.compress)
    374         self.assertRaises(TypeError, lzma.compress, [])
    375         self.assertRaises(TypeError, lzma.compress, b"", format="xz")
    376         self.assertRaises(TypeError, lzma.compress, b"", check="none")
    377         self.assertRaises(TypeError, lzma.compress, b"", preset="blah")
    378         self.assertRaises(TypeError, lzma.compress, b"", filters=1024)
    379         # Can't specify a preset and a custom filter chain at the same time.
    380         with self.assertRaises(ValueError):
    381             lzma.compress(b"", preset=3, filters=[{"id": lzma.FILTER_LZMA2}])
    382 
    383         self.assertRaises(TypeError, lzma.decompress)
    384         self.assertRaises(TypeError, lzma.decompress, [])
    385         self.assertRaises(TypeError, lzma.decompress, b"", format="lzma")
    386         self.assertRaises(TypeError, lzma.decompress, b"", memlimit=7.3e9)
    387         with self.assertRaises(TypeError):
    388             lzma.decompress(b"", format=lzma.FORMAT_RAW, filters={})
    389         # Cannot specify a memory limit with FILTER_RAW.
    390         with self.assertRaises(ValueError):
    391             lzma.decompress(b"", format=lzma.FORMAT_RAW, memlimit=0x1000000)
    392         # Can only specify a custom filter chain with FILTER_RAW.
    393         with self.assertRaises(ValueError):
    394             lzma.decompress(b"", filters=FILTERS_RAW_1)
    395         with self.assertRaises(ValueError):
    396             lzma.decompress(b"", format=lzma.FORMAT_XZ, filters=FILTERS_RAW_1)
    397         with self.assertRaises(ValueError):
    398             lzma.decompress(
    399                     b"", format=lzma.FORMAT_ALONE, filters=FILTERS_RAW_1)
    400 
    401     def test_decompress_memlimit(self):
    402         with self.assertRaises(LZMAError):
    403             lzma.decompress(COMPRESSED_XZ, memlimit=1024)
    404         with self.assertRaises(LZMAError):
    405             lzma.decompress(
    406                     COMPRESSED_XZ, format=lzma.FORMAT_XZ, memlimit=1024)
    407         with self.assertRaises(LZMAError):
    408             lzma.decompress(
    409                     COMPRESSED_ALONE, format=lzma.FORMAT_ALONE, memlimit=1024)
    410 
    411     # Test LZMADecompressor on known-good input data.
    412 
    413     def test_decompress_good_input(self):
    414         ddata = lzma.decompress(COMPRESSED_XZ)
    415         self.assertEqual(ddata, INPUT)
    416 
    417         ddata = lzma.decompress(COMPRESSED_ALONE)
    418         self.assertEqual(ddata, INPUT)
    419 
    420         ddata = lzma.decompress(COMPRESSED_XZ, lzma.FORMAT_XZ)
    421         self.assertEqual(ddata, INPUT)
    422 
    423         ddata = lzma.decompress(COMPRESSED_ALONE, lzma.FORMAT_ALONE)
    424         self.assertEqual(ddata, INPUT)
    425 
    426         ddata = lzma.decompress(
    427                 COMPRESSED_RAW_1, lzma.FORMAT_RAW, filters=FILTERS_RAW_1)
    428         self.assertEqual(ddata, INPUT)
    429 
    430         ddata = lzma.decompress(
    431                 COMPRESSED_RAW_2, lzma.FORMAT_RAW, filters=FILTERS_RAW_2)
    432         self.assertEqual(ddata, INPUT)
    433 
    434         ddata = lzma.decompress(
    435                 COMPRESSED_RAW_3, lzma.FORMAT_RAW, filters=FILTERS_RAW_3)
    436         self.assertEqual(ddata, INPUT)
    437 
    438         ddata = lzma.decompress(
    439                 COMPRESSED_RAW_4, lzma.FORMAT_RAW, filters=FILTERS_RAW_4)
    440         self.assertEqual(ddata, INPUT)
    441 
    442     def test_decompress_incomplete_input(self):
    443         self.assertRaises(LZMAError, lzma.decompress, COMPRESSED_XZ[:128])
    444         self.assertRaises(LZMAError, lzma.decompress, COMPRESSED_ALONE[:128])
    445         self.assertRaises(LZMAError, lzma.decompress, COMPRESSED_RAW_1[:128],
    446                           format=lzma.FORMAT_RAW, filters=FILTERS_RAW_1)
    447         self.assertRaises(LZMAError, lzma.decompress, COMPRESSED_RAW_2[:128],
    448                           format=lzma.FORMAT_RAW, filters=FILTERS_RAW_2)
    449         self.assertRaises(LZMAError, lzma.decompress, COMPRESSED_RAW_3[:128],
    450                           format=lzma.FORMAT_RAW, filters=FILTERS_RAW_3)
    451         self.assertRaises(LZMAError, lzma.decompress, COMPRESSED_RAW_4[:128],
    452                           format=lzma.FORMAT_RAW, filters=FILTERS_RAW_4)
    453 
    454     def test_decompress_bad_input(self):
    455         with self.assertRaises(LZMAError):
    456             lzma.decompress(COMPRESSED_BOGUS)
    457         with self.assertRaises(LZMAError):
    458             lzma.decompress(COMPRESSED_RAW_1)
    459         with self.assertRaises(LZMAError):
    460             lzma.decompress(COMPRESSED_ALONE, format=lzma.FORMAT_XZ)
    461         with self.assertRaises(LZMAError):
    462             lzma.decompress(COMPRESSED_XZ, format=lzma.FORMAT_ALONE)
    463         with self.assertRaises(LZMAError):
    464             lzma.decompress(COMPRESSED_XZ, format=lzma.FORMAT_RAW,
    465                             filters=FILTERS_RAW_1)
    466 
    467     # Test that compress()->decompress() preserves the input data.
    468 
    469     def test_roundtrip(self):
    470         cdata = lzma.compress(INPUT)
    471         ddata = lzma.decompress(cdata)
    472         self.assertEqual(ddata, INPUT)
    473 
    474         cdata = lzma.compress(INPUT, lzma.FORMAT_XZ)
    475         ddata = lzma.decompress(cdata)
    476         self.assertEqual(ddata, INPUT)
    477 
    478         cdata = lzma.compress(INPUT, lzma.FORMAT_ALONE)
    479         ddata = lzma.decompress(cdata)
    480         self.assertEqual(ddata, INPUT)
    481 
    482         cdata = lzma.compress(INPUT, lzma.FORMAT_RAW, filters=FILTERS_RAW_4)
    483         ddata = lzma.decompress(cdata, lzma.FORMAT_RAW, filters=FILTERS_RAW_4)
    484         self.assertEqual(ddata, INPUT)
    485 
    486     # Unlike LZMADecompressor, decompress() *does* handle concatenated streams.
    487 
    488     def test_decompress_multistream(self):
    489         ddata = lzma.decompress(COMPRESSED_XZ + COMPRESSED_ALONE)
    490         self.assertEqual(ddata, INPUT * 2)
    491 
    492     # Test robust handling of non-LZMA data following the compressed stream(s).
    493 
    494     def test_decompress_trailing_junk(self):
    495         ddata = lzma.decompress(COMPRESSED_XZ + COMPRESSED_BOGUS)
    496         self.assertEqual(ddata, INPUT)
    497 
    498     def test_decompress_multistream_trailing_junk(self):
    499         ddata = lzma.decompress(COMPRESSED_XZ * 3 + COMPRESSED_BOGUS)
    500         self.assertEqual(ddata, INPUT * 3)
    501 
    502 
    503 class TempFile:
    504     """Context manager - creates a file, and deletes it on __exit__."""
    505 
    506     def __init__(self, filename, data=b""):
    507         self.filename = filename
    508         self.data = data
    509 
    510     def __enter__(self):
    511         with open(self.filename, "wb") as f:
    512             f.write(self.data)
    513 
    514     def __exit__(self, *args):
    515         unlink(self.filename)
    516 
    517 
    518 class FileTestCase(unittest.TestCase):
    519 
    520     def test_init(self):
    521         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    522             pass
    523         with LZMAFile(BytesIO(), "w") as f:
    524             pass
    525         with LZMAFile(BytesIO(), "x") as f:
    526             pass
    527         with LZMAFile(BytesIO(), "a") as f:
    528             pass
    529 
    530     def test_init_with_PathLike_filename(self):
    531         filename = pathlib.Path(TESTFN)
    532         with TempFile(filename, COMPRESSED_XZ):
    533             with LZMAFile(filename) as f:
    534                 self.assertEqual(f.read(), INPUT)
    535             with LZMAFile(filename, "a") as f:
    536                 f.write(INPUT)
    537             with LZMAFile(filename) as f:
    538                 self.assertEqual(f.read(), INPUT * 2)
    539 
    540     def test_init_with_filename(self):
    541         with TempFile(TESTFN, COMPRESSED_XZ):
    542             with LZMAFile(TESTFN) as f:
    543                 pass
    544             with LZMAFile(TESTFN, "w") as f:
    545                 pass
    546             with LZMAFile(TESTFN, "a") as f:
    547                 pass
    548 
    549     def test_init_mode(self):
    550         with TempFile(TESTFN):
    551             with LZMAFile(TESTFN, "r"):
    552                 pass
    553             with LZMAFile(TESTFN, "rb"):
    554                 pass
    555             with LZMAFile(TESTFN, "w"):
    556                 pass
    557             with LZMAFile(TESTFN, "wb"):
    558                 pass
    559             with LZMAFile(TESTFN, "a"):
    560                 pass
    561             with LZMAFile(TESTFN, "ab"):
    562                 pass
    563 
    564     def test_init_with_x_mode(self):
    565         self.addCleanup(unlink, TESTFN)
    566         for mode in ("x", "xb"):
    567             unlink(TESTFN)
    568             with LZMAFile(TESTFN, mode):
    569                 pass
    570             with self.assertRaises(FileExistsError):
    571                 with LZMAFile(TESTFN, mode):
    572                     pass
    573 
    574     def test_init_bad_mode(self):
    575         with self.assertRaises(ValueError):
    576             LZMAFile(BytesIO(COMPRESSED_XZ), (3, "x"))
    577         with self.assertRaises(ValueError):
    578             LZMAFile(BytesIO(COMPRESSED_XZ), "")
    579         with self.assertRaises(ValueError):
    580             LZMAFile(BytesIO(COMPRESSED_XZ), "xt")
    581         with self.assertRaises(ValueError):
    582             LZMAFile(BytesIO(COMPRESSED_XZ), "x+")
    583         with self.assertRaises(ValueError):
    584             LZMAFile(BytesIO(COMPRESSED_XZ), "rx")
    585         with self.assertRaises(ValueError):
    586             LZMAFile(BytesIO(COMPRESSED_XZ), "wx")
    587         with self.assertRaises(ValueError):
    588             LZMAFile(BytesIO(COMPRESSED_XZ), "rt")
    589         with self.assertRaises(ValueError):
    590             LZMAFile(BytesIO(COMPRESSED_XZ), "r+")
    591         with self.assertRaises(ValueError):
    592             LZMAFile(BytesIO(COMPRESSED_XZ), "wt")
    593         with self.assertRaises(ValueError):
    594             LZMAFile(BytesIO(COMPRESSED_XZ), "w+")
    595         with self.assertRaises(ValueError):
    596             LZMAFile(BytesIO(COMPRESSED_XZ), "rw")
    597 
    598     def test_init_bad_check(self):
    599         with self.assertRaises(TypeError):
    600             LZMAFile(BytesIO(), "w", check=b"asd")
    601         # CHECK_UNKNOWN and anything above CHECK_ID_MAX should be invalid.
    602         with self.assertRaises(LZMAError):
    603             LZMAFile(BytesIO(), "w", check=lzma.CHECK_UNKNOWN)
    604         with self.assertRaises(LZMAError):
    605             LZMAFile(BytesIO(), "w", check=lzma.CHECK_ID_MAX + 3)
    606         # Cannot specify a check with mode="r".
    607         with self.assertRaises(ValueError):
    608             LZMAFile(BytesIO(COMPRESSED_XZ), check=lzma.CHECK_NONE)
    609         with self.assertRaises(ValueError):
    610             LZMAFile(BytesIO(COMPRESSED_XZ), check=lzma.CHECK_CRC32)
    611         with self.assertRaises(ValueError):
    612             LZMAFile(BytesIO(COMPRESSED_XZ), check=lzma.CHECK_CRC64)
    613         with self.assertRaises(ValueError):
    614             LZMAFile(BytesIO(COMPRESSED_XZ), check=lzma.CHECK_SHA256)
    615         with self.assertRaises(ValueError):
    616             LZMAFile(BytesIO(COMPRESSED_XZ), check=lzma.CHECK_UNKNOWN)
    617 
    618     def test_init_bad_preset(self):
    619         with self.assertRaises(TypeError):
    620             LZMAFile(BytesIO(), "w", preset=4.39)
    621         with self.assertRaises(LZMAError):
    622             LZMAFile(BytesIO(), "w", preset=10)
    623         with self.assertRaises(LZMAError):
    624             LZMAFile(BytesIO(), "w", preset=23)
    625         with self.assertRaises(OverflowError):
    626             LZMAFile(BytesIO(), "w", preset=-1)
    627         with self.assertRaises(OverflowError):
    628             LZMAFile(BytesIO(), "w", preset=-7)
    629         with self.assertRaises(TypeError):
    630             LZMAFile(BytesIO(), "w", preset="foo")
    631         # Cannot specify a preset with mode="r".
    632         with self.assertRaises(ValueError):
    633             LZMAFile(BytesIO(COMPRESSED_XZ), preset=3)
    634 
    635     def test_init_bad_filter_spec(self):
    636         with self.assertRaises(TypeError):
    637             LZMAFile(BytesIO(), "w", filters=[b"wobsite"])
    638         with self.assertRaises(ValueError):
    639             LZMAFile(BytesIO(), "w", filters=[{"xyzzy": 3}])
    640         with self.assertRaises(ValueError):
    641             LZMAFile(BytesIO(), "w", filters=[{"id": 98765}])
    642         with self.assertRaises(ValueError):
    643             LZMAFile(BytesIO(), "w",
    644                      filters=[{"id": lzma.FILTER_LZMA2, "foo": 0}])
    645         with self.assertRaises(ValueError):
    646             LZMAFile(BytesIO(), "w",
    647                      filters=[{"id": lzma.FILTER_DELTA, "foo": 0}])
    648         with self.assertRaises(ValueError):
    649             LZMAFile(BytesIO(), "w",
    650                      filters=[{"id": lzma.FILTER_X86, "foo": 0}])
    651 
    652     def test_init_with_preset_and_filters(self):
    653         with self.assertRaises(ValueError):
    654             LZMAFile(BytesIO(), "w", format=lzma.FORMAT_RAW,
    655                      preset=6, filters=FILTERS_RAW_1)
    656 
    657     def test_close(self):
    658         with BytesIO(COMPRESSED_XZ) as src:
    659             f = LZMAFile(src)
    660             f.close()
    661             # LZMAFile.close() should not close the underlying file object.
    662             self.assertFalse(src.closed)
    663             # Try closing an already-closed LZMAFile.
    664             f.close()
    665             self.assertFalse(src.closed)
    666 
    667         # Test with a real file on disk, opened directly by LZMAFile.
    668         with TempFile(TESTFN, COMPRESSED_XZ):
    669             f = LZMAFile(TESTFN)
    670             fp = f._fp
    671             f.close()
    672             # Here, LZMAFile.close() *should* close the underlying file object.
    673             self.assertTrue(fp.closed)
    674             # Try closing an already-closed LZMAFile.
    675             f.close()
    676 
    677     def test_closed(self):
    678         f = LZMAFile(BytesIO(COMPRESSED_XZ))
    679         try:
    680             self.assertFalse(f.closed)
    681             f.read()
    682             self.assertFalse(f.closed)
    683         finally:
    684             f.close()
    685         self.assertTrue(f.closed)
    686 
    687         f = LZMAFile(BytesIO(), "w")
    688         try:
    689             self.assertFalse(f.closed)
    690         finally:
    691             f.close()
    692         self.assertTrue(f.closed)
    693 
    694     def test_fileno(self):
    695         f = LZMAFile(BytesIO(COMPRESSED_XZ))
    696         try:
    697             self.assertRaises(UnsupportedOperation, f.fileno)
    698         finally:
    699             f.close()
    700         self.assertRaises(ValueError, f.fileno)
    701         with TempFile(TESTFN, COMPRESSED_XZ):
    702             f = LZMAFile(TESTFN)
    703             try:
    704                 self.assertEqual(f.fileno(), f._fp.fileno())
    705                 self.assertIsInstance(f.fileno(), int)
    706             finally:
    707                 f.close()
    708         self.assertRaises(ValueError, f.fileno)
    709 
    710     def test_seekable(self):
    711         f = LZMAFile(BytesIO(COMPRESSED_XZ))
    712         try:
    713             self.assertTrue(f.seekable())
    714             f.read()
    715             self.assertTrue(f.seekable())
    716         finally:
    717             f.close()
    718         self.assertRaises(ValueError, f.seekable)
    719 
    720         f = LZMAFile(BytesIO(), "w")
    721         try:
    722             self.assertFalse(f.seekable())
    723         finally:
    724             f.close()
    725         self.assertRaises(ValueError, f.seekable)
    726 
    727         src = BytesIO(COMPRESSED_XZ)
    728         src.seekable = lambda: False
    729         f = LZMAFile(src)
    730         try:
    731             self.assertFalse(f.seekable())
    732         finally:
    733             f.close()
    734         self.assertRaises(ValueError, f.seekable)
    735 
    736     def test_readable(self):
    737         f = LZMAFile(BytesIO(COMPRESSED_XZ))
    738         try:
    739             self.assertTrue(f.readable())
    740             f.read()
    741             self.assertTrue(f.readable())
    742         finally:
    743             f.close()
    744         self.assertRaises(ValueError, f.readable)
    745 
    746         f = LZMAFile(BytesIO(), "w")
    747         try:
    748             self.assertFalse(f.readable())
    749         finally:
    750             f.close()
    751         self.assertRaises(ValueError, f.readable)
    752 
    753     def test_writable(self):
    754         f = LZMAFile(BytesIO(COMPRESSED_XZ))
    755         try:
    756             self.assertFalse(f.writable())
    757             f.read()
    758             self.assertFalse(f.writable())
    759         finally:
    760             f.close()
    761         self.assertRaises(ValueError, f.writable)
    762 
    763         f = LZMAFile(BytesIO(), "w")
    764         try:
    765             self.assertTrue(f.writable())
    766         finally:
    767             f.close()
    768         self.assertRaises(ValueError, f.writable)
    769 
    770     def test_read(self):
    771         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    772             self.assertEqual(f.read(), INPUT)
    773             self.assertEqual(f.read(), b"")
    774         with LZMAFile(BytesIO(COMPRESSED_ALONE)) as f:
    775             self.assertEqual(f.read(), INPUT)
    776         with LZMAFile(BytesIO(COMPRESSED_XZ), format=lzma.FORMAT_XZ) as f:
    777             self.assertEqual(f.read(), INPUT)
    778             self.assertEqual(f.read(), b"")
    779         with LZMAFile(BytesIO(COMPRESSED_ALONE), format=lzma.FORMAT_ALONE) as f:
    780             self.assertEqual(f.read(), INPUT)
    781             self.assertEqual(f.read(), b"")
    782         with LZMAFile(BytesIO(COMPRESSED_RAW_1),
    783                       format=lzma.FORMAT_RAW, filters=FILTERS_RAW_1) as f:
    784             self.assertEqual(f.read(), INPUT)
    785             self.assertEqual(f.read(), b"")
    786         with LZMAFile(BytesIO(COMPRESSED_RAW_2),
    787                       format=lzma.FORMAT_RAW, filters=FILTERS_RAW_2) as f:
    788             self.assertEqual(f.read(), INPUT)
    789             self.assertEqual(f.read(), b"")
    790         with LZMAFile(BytesIO(COMPRESSED_RAW_3),
    791                       format=lzma.FORMAT_RAW, filters=FILTERS_RAW_3) as f:
    792             self.assertEqual(f.read(), INPUT)
    793             self.assertEqual(f.read(), b"")
    794         with LZMAFile(BytesIO(COMPRESSED_RAW_4),
    795                       format=lzma.FORMAT_RAW, filters=FILTERS_RAW_4) as f:
    796             self.assertEqual(f.read(), INPUT)
    797             self.assertEqual(f.read(), b"")
    798 
    799     def test_read_0(self):
    800         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    801             self.assertEqual(f.read(0), b"")
    802         with LZMAFile(BytesIO(COMPRESSED_ALONE)) as f:
    803             self.assertEqual(f.read(0), b"")
    804         with LZMAFile(BytesIO(COMPRESSED_XZ), format=lzma.FORMAT_XZ) as f:
    805             self.assertEqual(f.read(0), b"")
    806         with LZMAFile(BytesIO(COMPRESSED_ALONE), format=lzma.FORMAT_ALONE) as f:
    807             self.assertEqual(f.read(0), b"")
    808 
    809     def test_read_10(self):
    810         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    811             chunks = []
    812             while True:
    813                 result = f.read(10)
    814                 if not result:
    815                     break
    816                 self.assertLessEqual(len(result), 10)
    817                 chunks.append(result)
    818             self.assertEqual(b"".join(chunks), INPUT)
    819 
    820     def test_read_multistream(self):
    821         with LZMAFile(BytesIO(COMPRESSED_XZ * 5)) as f:
    822             self.assertEqual(f.read(), INPUT * 5)
    823         with LZMAFile(BytesIO(COMPRESSED_XZ + COMPRESSED_ALONE)) as f:
    824             self.assertEqual(f.read(), INPUT * 2)
    825         with LZMAFile(BytesIO(COMPRESSED_RAW_3 * 4),
    826                       format=lzma.FORMAT_RAW, filters=FILTERS_RAW_3) as f:
    827             self.assertEqual(f.read(), INPUT * 4)
    828 
    829     def test_read_multistream_buffer_size_aligned(self):
    830         # Test the case where a stream boundary coincides with the end
    831         # of the raw read buffer.
    832         saved_buffer_size = _compression.BUFFER_SIZE
    833         _compression.BUFFER_SIZE = len(COMPRESSED_XZ)
    834         try:
    835             with LZMAFile(BytesIO(COMPRESSED_XZ *  5)) as f:
    836                 self.assertEqual(f.read(), INPUT * 5)
    837         finally:
    838             _compression.BUFFER_SIZE = saved_buffer_size
    839 
    840     def test_read_trailing_junk(self):
    841         with LZMAFile(BytesIO(COMPRESSED_XZ + COMPRESSED_BOGUS)) as f:
    842             self.assertEqual(f.read(), INPUT)
    843 
    844     def test_read_multistream_trailing_junk(self):
    845         with LZMAFile(BytesIO(COMPRESSED_XZ * 5 + COMPRESSED_BOGUS)) as f:
    846             self.assertEqual(f.read(), INPUT * 5)
    847 
    848     def test_read_from_file(self):
    849         with TempFile(TESTFN, COMPRESSED_XZ):
    850             with LZMAFile(TESTFN) as f:
    851                 self.assertEqual(f.read(), INPUT)
    852                 self.assertEqual(f.read(), b"")
    853 
    854     def test_read_from_file_with_bytes_filename(self):
    855         try:
    856             bytes_filename = TESTFN.encode("ascii")
    857         except UnicodeEncodeError:
    858             self.skipTest("Temporary file name needs to be ASCII")
    859         with TempFile(TESTFN, COMPRESSED_XZ):
    860             with LZMAFile(bytes_filename) as f:
    861                 self.assertEqual(f.read(), INPUT)
    862                 self.assertEqual(f.read(), b"")
    863 
    864     def test_read_incomplete(self):
    865         with LZMAFile(BytesIO(COMPRESSED_XZ[:128])) as f:
    866             self.assertRaises(EOFError, f.read)
    867 
    868     def test_read_truncated(self):
    869         # Drop stream footer: CRC (4 bytes), index size (4 bytes),
    870         # flags (2 bytes) and magic number (2 bytes).
    871         truncated = COMPRESSED_XZ[:-12]
    872         with LZMAFile(BytesIO(truncated)) as f:
    873             self.assertRaises(EOFError, f.read)
    874         with LZMAFile(BytesIO(truncated)) as f:
    875             self.assertEqual(f.read(len(INPUT)), INPUT)
    876             self.assertRaises(EOFError, f.read, 1)
    877         # Incomplete 12-byte header.
    878         for i in range(12):
    879             with LZMAFile(BytesIO(truncated[:i])) as f:
    880                 self.assertRaises(EOFError, f.read, 1)
    881 
    882     def test_read_bad_args(self):
    883         f = LZMAFile(BytesIO(COMPRESSED_XZ))
    884         f.close()
    885         self.assertRaises(ValueError, f.read)
    886         with LZMAFile(BytesIO(), "w") as f:
    887             self.assertRaises(ValueError, f.read)
    888         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    889             self.assertRaises(TypeError, f.read, float())
    890 
    891     def test_read_bad_data(self):
    892         with LZMAFile(BytesIO(COMPRESSED_BOGUS)) as f:
    893             self.assertRaises(LZMAError, f.read)
    894 
    895     def test_read1(self):
    896         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    897             blocks = []
    898             while True:
    899                 result = f.read1()
    900                 if not result:
    901                     break
    902                 blocks.append(result)
    903             self.assertEqual(b"".join(blocks), INPUT)
    904             self.assertEqual(f.read1(), b"")
    905 
    906     def test_read1_0(self):
    907         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    908             self.assertEqual(f.read1(0), b"")
    909 
    910     def test_read1_10(self):
    911         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    912             blocks = []
    913             while True:
    914                 result = f.read1(10)
    915                 if not result:
    916                     break
    917                 blocks.append(result)
    918             self.assertEqual(b"".join(blocks), INPUT)
    919             self.assertEqual(f.read1(), b"")
    920 
    921     def test_read1_multistream(self):
    922         with LZMAFile(BytesIO(COMPRESSED_XZ * 5)) as f:
    923             blocks = []
    924             while True:
    925                 result = f.read1()
    926                 if not result:
    927                     break
    928                 blocks.append(result)
    929             self.assertEqual(b"".join(blocks), INPUT * 5)
    930             self.assertEqual(f.read1(), b"")
    931 
    932     def test_read1_bad_args(self):
    933         f = LZMAFile(BytesIO(COMPRESSED_XZ))
    934         f.close()
    935         self.assertRaises(ValueError, f.read1)
    936         with LZMAFile(BytesIO(), "w") as f:
    937             self.assertRaises(ValueError, f.read1)
    938         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    939             self.assertRaises(TypeError, f.read1, None)
    940 
    941     def test_peek(self):
    942         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    943             result = f.peek()
    944             self.assertGreater(len(result), 0)
    945             self.assertTrue(INPUT.startswith(result))
    946             self.assertEqual(f.read(), INPUT)
    947         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    948             result = f.peek(10)
    949             self.assertGreater(len(result), 0)
    950             self.assertTrue(INPUT.startswith(result))
    951             self.assertEqual(f.read(), INPUT)
    952 
    953     def test_peek_bad_args(self):
    954         with LZMAFile(BytesIO(), "w") as f:
    955             self.assertRaises(ValueError, f.peek)
    956 
    957     def test_iterator(self):
    958         with BytesIO(INPUT) as f:
    959             lines = f.readlines()
    960         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    961             self.assertListEqual(list(iter(f)), lines)
    962         with LZMAFile(BytesIO(COMPRESSED_ALONE)) as f:
    963             self.assertListEqual(list(iter(f)), lines)
    964         with LZMAFile(BytesIO(COMPRESSED_XZ), format=lzma.FORMAT_XZ) as f:
    965             self.assertListEqual(list(iter(f)), lines)
    966         with LZMAFile(BytesIO(COMPRESSED_ALONE), format=lzma.FORMAT_ALONE) as f:
    967             self.assertListEqual(list(iter(f)), lines)
    968         with LZMAFile(BytesIO(COMPRESSED_RAW_2),
    969                       format=lzma.FORMAT_RAW, filters=FILTERS_RAW_2) as f:
    970             self.assertListEqual(list(iter(f)), lines)
    971 
    972     def test_readline(self):
    973         with BytesIO(INPUT) as f:
    974             lines = f.readlines()
    975         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    976             for line in lines:
    977                 self.assertEqual(f.readline(), line)
    978 
    979     def test_readlines(self):
    980         with BytesIO(INPUT) as f:
    981             lines = f.readlines()
    982         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
    983             self.assertListEqual(f.readlines(), lines)
    984 
    985     def test_decompress_limited(self):
    986         """Decompressed data buffering should be limited"""
    987         bomb = lzma.compress(b'\0' * int(2e6), preset=6)
    988         self.assertLess(len(bomb), _compression.BUFFER_SIZE)
    989 
    990         decomp = LZMAFile(BytesIO(bomb))
    991         self.assertEqual(decomp.read(1), b'\0')
    992         max_decomp = 1 + DEFAULT_BUFFER_SIZE
    993         self.assertLessEqual(decomp._buffer.raw.tell(), max_decomp,
    994             "Excessive amount of data was decompressed")
    995 
    996     def test_write(self):
    997         with BytesIO() as dst:
    998             with LZMAFile(dst, "w") as f:
    999                 f.write(INPUT)
   1000             expected = lzma.compress(INPUT)
   1001             self.assertEqual(dst.getvalue(), expected)
   1002         with BytesIO() as dst:
   1003             with LZMAFile(dst, "w", format=lzma.FORMAT_XZ) as f:
   1004                 f.write(INPUT)
   1005             expected = lzma.compress(INPUT, format=lzma.FORMAT_XZ)
   1006             self.assertEqual(dst.getvalue(), expected)
   1007         with BytesIO() as dst:
   1008             with LZMAFile(dst, "w", format=lzma.FORMAT_ALONE) as f:
   1009                 f.write(INPUT)
   1010             expected = lzma.compress(INPUT, format=lzma.FORMAT_ALONE)
   1011             self.assertEqual(dst.getvalue(), expected)
   1012         with BytesIO() as dst:
   1013             with LZMAFile(dst, "w", format=lzma.FORMAT_RAW,
   1014                           filters=FILTERS_RAW_2) as f:
   1015                 f.write(INPUT)
   1016             expected = lzma.compress(INPUT, format=lzma.FORMAT_RAW,
   1017                                      filters=FILTERS_RAW_2)
   1018             self.assertEqual(dst.getvalue(), expected)
   1019 
   1020     def test_write_10(self):
   1021         with BytesIO() as dst:
   1022             with LZMAFile(dst, "w") as f:
   1023                 for start in range(0, len(INPUT), 10):
   1024                     f.write(INPUT[start:start+10])
   1025             expected = lzma.compress(INPUT)
   1026             self.assertEqual(dst.getvalue(), expected)
   1027 
   1028     def test_write_append(self):
   1029         part1 = INPUT[:1024]
   1030         part2 = INPUT[1024:1536]
   1031         part3 = INPUT[1536:]
   1032         expected = b"".join(lzma.compress(x) for x in (part1, part2, part3))
   1033         with BytesIO() as dst:
   1034             with LZMAFile(dst, "w") as f:
   1035                 f.write(part1)
   1036             with LZMAFile(dst, "a") as f:
   1037                 f.write(part2)
   1038             with LZMAFile(dst, "a") as f:
   1039                 f.write(part3)
   1040             self.assertEqual(dst.getvalue(), expected)
   1041 
   1042     def test_write_to_file(self):
   1043         try:
   1044             with LZMAFile(TESTFN, "w") as f:
   1045                 f.write(INPUT)
   1046             expected = lzma.compress(INPUT)
   1047             with open(TESTFN, "rb") as f:
   1048                 self.assertEqual(f.read(), expected)
   1049         finally:
   1050             unlink(TESTFN)
   1051 
   1052     def test_write_to_file_with_bytes_filename(self):
   1053         try:
   1054             bytes_filename = TESTFN.encode("ascii")
   1055         except UnicodeEncodeError:
   1056             self.skipTest("Temporary file name needs to be ASCII")
   1057         try:
   1058             with LZMAFile(bytes_filename, "w") as f:
   1059                 f.write(INPUT)
   1060             expected = lzma.compress(INPUT)
   1061             with open(TESTFN, "rb") as f:
   1062                 self.assertEqual(f.read(), expected)
   1063         finally:
   1064             unlink(TESTFN)
   1065 
   1066     def test_write_append_to_file(self):
   1067         part1 = INPUT[:1024]
   1068         part2 = INPUT[1024:1536]
   1069         part3 = INPUT[1536:]
   1070         expected = b"".join(lzma.compress(x) for x in (part1, part2, part3))
   1071         try:
   1072             with LZMAFile(TESTFN, "w") as f:
   1073                 f.write(part1)
   1074             with LZMAFile(TESTFN, "a") as f:
   1075                 f.write(part2)
   1076             with LZMAFile(TESTFN, "a") as f:
   1077                 f.write(part3)
   1078             with open(TESTFN, "rb") as f:
   1079                 self.assertEqual(f.read(), expected)
   1080         finally:
   1081             unlink(TESTFN)
   1082 
   1083     def test_write_bad_args(self):
   1084         f = LZMAFile(BytesIO(), "w")
   1085         f.close()
   1086         self.assertRaises(ValueError, f.write, b"foo")
   1087         with LZMAFile(BytesIO(COMPRESSED_XZ), "r") as f:
   1088             self.assertRaises(ValueError, f.write, b"bar")
   1089         with LZMAFile(BytesIO(), "w") as f:
   1090             self.assertRaises(TypeError, f.write, None)
   1091             self.assertRaises(TypeError, f.write, "text")
   1092             self.assertRaises(TypeError, f.write, 789)
   1093 
   1094     def test_writelines(self):
   1095         with BytesIO(INPUT) as f:
   1096             lines = f.readlines()
   1097         with BytesIO() as dst:
   1098             with LZMAFile(dst, "w") as f:
   1099                 f.writelines(lines)
   1100             expected = lzma.compress(INPUT)
   1101             self.assertEqual(dst.getvalue(), expected)
   1102 
   1103     def test_seek_forward(self):
   1104         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
   1105             f.seek(555)
   1106             self.assertEqual(f.read(), INPUT[555:])
   1107 
   1108     def test_seek_forward_across_streams(self):
   1109         with LZMAFile(BytesIO(COMPRESSED_XZ * 2)) as f:
   1110             f.seek(len(INPUT) + 123)
   1111             self.assertEqual(f.read(), INPUT[123:])
   1112 
   1113     def test_seek_forward_relative_to_current(self):
   1114         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
   1115             f.read(100)
   1116             f.seek(1236, 1)
   1117             self.assertEqual(f.read(), INPUT[1336:])
   1118 
   1119     def test_seek_forward_relative_to_end(self):
   1120         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
   1121             f.seek(-555, 2)
   1122             self.assertEqual(f.read(), INPUT[-555:])
   1123 
   1124     def test_seek_backward(self):
   1125         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
   1126             f.read(1001)
   1127             f.seek(211)
   1128             self.assertEqual(f.read(), INPUT[211:])
   1129 
   1130     def test_seek_backward_across_streams(self):
   1131         with LZMAFile(BytesIO(COMPRESSED_XZ * 2)) as f:
   1132             f.read(len(INPUT) + 333)
   1133             f.seek(737)
   1134             self.assertEqual(f.read(), INPUT[737:] + INPUT)
   1135 
   1136     def test_seek_backward_relative_to_end(self):
   1137         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
   1138             f.seek(-150, 2)
   1139             self.assertEqual(f.read(), INPUT[-150:])
   1140 
   1141     def test_seek_past_end(self):
   1142         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
   1143             f.seek(len(INPUT) + 9001)
   1144             self.assertEqual(f.tell(), len(INPUT))
   1145             self.assertEqual(f.read(), b"")
   1146 
   1147     def test_seek_past_start(self):
   1148         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
   1149             f.seek(-88)
   1150             self.assertEqual(f.tell(), 0)
   1151             self.assertEqual(f.read(), INPUT)
   1152 
   1153     def test_seek_bad_args(self):
   1154         f = LZMAFile(BytesIO(COMPRESSED_XZ))
   1155         f.close()
   1156         self.assertRaises(ValueError, f.seek, 0)
   1157         with LZMAFile(BytesIO(), "w") as f:
   1158             self.assertRaises(ValueError, f.seek, 0)
   1159         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
   1160             self.assertRaises(ValueError, f.seek, 0, 3)
   1161             # io.BufferedReader raises TypeError instead of ValueError
   1162             self.assertRaises((TypeError, ValueError), f.seek, 9, ())
   1163             self.assertRaises(TypeError, f.seek, None)
   1164             self.assertRaises(TypeError, f.seek, b"derp")
   1165 
   1166     def test_tell(self):
   1167         with LZMAFile(BytesIO(COMPRESSED_XZ)) as f:
   1168             pos = 0
   1169             while True:
   1170                 self.assertEqual(f.tell(), pos)
   1171                 result = f.read(183)
   1172                 if not result:
   1173                     break
   1174                 pos += len(result)
   1175             self.assertEqual(f.tell(), len(INPUT))
   1176         with LZMAFile(BytesIO(), "w") as f:
   1177             for pos in range(0, len(INPUT), 144):
   1178                 self.assertEqual(f.tell(), pos)
   1179                 f.write(INPUT[pos:pos+144])
   1180             self.assertEqual(f.tell(), len(INPUT))
   1181 
   1182     def test_tell_bad_args(self):
   1183         f = LZMAFile(BytesIO(COMPRESSED_XZ))
   1184         f.close()
   1185         self.assertRaises(ValueError, f.tell)
   1186 
   1187 
   1188 class OpenTestCase(unittest.TestCase):
   1189 
   1190     def test_binary_modes(self):
   1191         with lzma.open(BytesIO(COMPRESSED_XZ), "rb") as f:
   1192             self.assertEqual(f.read(), INPUT)
   1193         with BytesIO() as bio:
   1194             with lzma.open(bio, "wb") as f:
   1195                 f.write(INPUT)
   1196             file_data = lzma.decompress(bio.getvalue())
   1197             self.assertEqual(file_data, INPUT)
   1198             with lzma.open(bio, "ab") as f:
   1199                 f.write(INPUT)
   1200             file_data = lzma.decompress(bio.getvalue())
   1201             self.assertEqual(file_data, INPUT * 2)
   1202 
   1203     def test_text_modes(self):
   1204         uncompressed = INPUT.decode("ascii")
   1205         uncompressed_raw = uncompressed.replace("\n", os.linesep)
   1206         with lzma.open(BytesIO(COMPRESSED_XZ), "rt") as f:
   1207             self.assertEqual(f.read(), uncompressed)
   1208         with BytesIO() as bio:
   1209             with lzma.open(bio, "wt") as f:
   1210                 f.write(uncompressed)
   1211             file_data = lzma.decompress(bio.getvalue()).decode("ascii")
   1212             self.assertEqual(file_data, uncompressed_raw)
   1213             with lzma.open(bio, "at") as f:
   1214                 f.write(uncompressed)
   1215             file_data = lzma.decompress(bio.getvalue()).decode("ascii")
   1216             self.assertEqual(file_data, uncompressed_raw * 2)
   1217 
   1218     def test_filename(self):
   1219         with TempFile(TESTFN):
   1220             with lzma.open(TESTFN, "wb") as f:
   1221                 f.write(INPUT)
   1222             with open(TESTFN, "rb") as f:
   1223                 file_data = lzma.decompress(f.read())
   1224                 self.assertEqual(file_data, INPUT)
   1225             with lzma.open(TESTFN, "rb") as f:
   1226                 self.assertEqual(f.read(), INPUT)
   1227             with lzma.open(TESTFN, "ab") as f:
   1228                 f.write(INPUT)
   1229             with lzma.open(TESTFN, "rb") as f:
   1230                 self.assertEqual(f.read(), INPUT * 2)
   1231 
   1232     def test_with_pathlike_filename(self):
   1233         filename = pathlib.Path(TESTFN)
   1234         with TempFile(filename):
   1235             with lzma.open(filename, "wb") as f:
   1236                 f.write(INPUT)
   1237             with open(filename, "rb") as f:
   1238                 file_data = lzma.decompress(f.read())
   1239                 self.assertEqual(file_data, INPUT)
   1240             with lzma.open(filename, "rb") as f:
   1241                 self.assertEqual(f.read(), INPUT)
   1242 
   1243     def test_bad_params(self):
   1244         # Test invalid parameter combinations.
   1245         with self.assertRaises(ValueError):
   1246             lzma.open(TESTFN, "")
   1247         with self.assertRaises(ValueError):
   1248             lzma.open(TESTFN, "rbt")
   1249         with self.assertRaises(ValueError):
   1250             lzma.open(TESTFN, "rb", encoding="utf-8")
   1251         with self.assertRaises(ValueError):
   1252             lzma.open(TESTFN, "rb", errors="ignore")
   1253         with self.assertRaises(ValueError):
   1254             lzma.open(TESTFN, "rb", newline="\n")
   1255 
   1256     def test_format_and_filters(self):
   1257         # Test non-default format and filter chain.
   1258         options = {"format": lzma.FORMAT_RAW, "filters": FILTERS_RAW_1}
   1259         with lzma.open(BytesIO(COMPRESSED_RAW_1), "rb", **options) as f:
   1260             self.assertEqual(f.read(), INPUT)
   1261         with BytesIO() as bio:
   1262             with lzma.open(bio, "wb", **options) as f:
   1263                 f.write(INPUT)
   1264             file_data = lzma.decompress(bio.getvalue(), **options)
   1265             self.assertEqual(file_data, INPUT)
   1266 
   1267     def test_encoding(self):
   1268         # Test non-default encoding.
   1269         uncompressed = INPUT.decode("ascii")
   1270         uncompressed_raw = uncompressed.replace("\n", os.linesep)
   1271         with BytesIO() as bio:
   1272             with lzma.open(bio, "wt", encoding="utf-16-le") as f:
   1273                 f.write(uncompressed)
   1274             file_data = lzma.decompress(bio.getvalue()).decode("utf-16-le")
   1275             self.assertEqual(file_data, uncompressed_raw)
   1276             bio.seek(0)
   1277             with lzma.open(bio, "rt", encoding="utf-16-le") as f:
   1278                 self.assertEqual(f.read(), uncompressed)
   1279 
   1280     def test_encoding_error_handler(self):
   1281         # Test with non-default encoding error handler.
   1282         with BytesIO(lzma.compress(b"foo\xffbar")) as bio:
   1283             with lzma.open(bio, "rt", encoding="ascii", errors="ignore") as f:
   1284                 self.assertEqual(f.read(), "foobar")
   1285 
   1286     def test_newline(self):
   1287         # Test with explicit newline (universal newline mode disabled).
   1288         text = INPUT.decode("ascii")
   1289         with BytesIO() as bio:
   1290             with lzma.open(bio, "wt", newline="\n") as f:
   1291                 f.write(text)
   1292             bio.seek(0)
   1293             with lzma.open(bio, "rt", newline="\r") as f:
   1294                 self.assertEqual(f.readlines(), [text])
   1295 
   1296     def test_x_mode(self):
   1297         self.addCleanup(unlink, TESTFN)
   1298         for mode in ("x", "xb", "xt"):
   1299             unlink(TESTFN)
   1300             with lzma.open(TESTFN, mode):
   1301                 pass
   1302             with self.assertRaises(FileExistsError):
   1303                 with lzma.open(TESTFN, mode):
   1304                     pass
   1305 
   1306 
   1307 class MiscellaneousTestCase(unittest.TestCase):
   1308 
   1309     def test_is_check_supported(self):
   1310         # CHECK_NONE and CHECK_CRC32 should always be supported,
   1311         # regardless of the options liblzma was compiled with.
   1312         self.assertTrue(lzma.is_check_supported(lzma.CHECK_NONE))
   1313         self.assertTrue(lzma.is_check_supported(lzma.CHECK_CRC32))
   1314 
   1315         # The .xz format spec cannot store check IDs above this value.
   1316         self.assertFalse(lzma.is_check_supported(lzma.CHECK_ID_MAX + 1))
   1317 
   1318         # This value should not be a valid check ID.
   1319         self.assertFalse(lzma.is_check_supported(lzma.CHECK_UNKNOWN))
   1320 
   1321     def test__encode_filter_properties(self):
   1322         with self.assertRaises(TypeError):
   1323             lzma._encode_filter_properties(b"not a dict")
   1324         with self.assertRaises(ValueError):
   1325             lzma._encode_filter_properties({"id": 0x100})
   1326         with self.assertRaises(ValueError):
   1327             lzma._encode_filter_properties({"id": lzma.FILTER_LZMA2, "junk": 12})
   1328         with self.assertRaises(lzma.LZMAError):
   1329             lzma._encode_filter_properties({"id": lzma.FILTER_DELTA,
   1330                                            "dist": 9001})
   1331 
   1332         # Test with parameters used by zipfile module.
   1333         props = lzma._encode_filter_properties({
   1334                 "id": lzma.FILTER_LZMA1,
   1335                 "pb": 2,
   1336                 "lp": 0,
   1337                 "lc": 3,
   1338                 "dict_size": 8 << 20,
   1339             })
   1340         self.assertEqual(props, b"]\x00\x00\x80\x00")
   1341 
   1342     def test__decode_filter_properties(self):
   1343         with self.assertRaises(TypeError):
   1344             lzma._decode_filter_properties(lzma.FILTER_X86, {"should be": bytes})
   1345         with self.assertRaises(lzma.LZMAError):
   1346             lzma._decode_filter_properties(lzma.FILTER_DELTA, b"too long")
   1347 
   1348         # Test with parameters used by zipfile module.
   1349         filterspec = lzma._decode_filter_properties(
   1350                 lzma.FILTER_LZMA1, b"]\x00\x00\x80\x00")
   1351         self.assertEqual(filterspec["id"], lzma.FILTER_LZMA1)
   1352         self.assertEqual(filterspec["pb"], 2)
   1353         self.assertEqual(filterspec["lp"], 0)
   1354         self.assertEqual(filterspec["lc"], 3)
   1355         self.assertEqual(filterspec["dict_size"], 8 << 20)
   1356 
   1357     def test_filter_properties_roundtrip(self):
   1358         spec1 = lzma._decode_filter_properties(
   1359                 lzma.FILTER_LZMA1, b"]\x00\x00\x80\x00")
   1360         reencoded = lzma._encode_filter_properties(spec1)
   1361         spec2 = lzma._decode_filter_properties(lzma.FILTER_LZMA1, reencoded)
   1362         self.assertEqual(spec1, spec2)
   1363 
   1364 
   1365 # Test data:
   1366 
   1367 INPUT = b"""
   1368 LAERTES
   1369 
   1370        O, fear me not.
   1371        I stay too long: but here my father comes.
   1372 
   1373        Enter POLONIUS
   1374 
   1375        A double blessing is a double grace,
   1376        Occasion smiles upon a second leave.
   1377 
   1378 LORD POLONIUS
   1379 
   1380        Yet here, Laertes! aboard, aboard, for shame!
   1381        The wind sits in the shoulder of your sail,
   1382        And you are stay'd for. There; my blessing with thee!
   1383        And these few precepts in thy memory
   1384        See thou character. Give thy thoughts no tongue,
   1385        Nor any unproportioned thought his act.
   1386        Be thou familiar, but by no means vulgar.
   1387        Those friends thou hast, and their adoption tried,
   1388        Grapple them to thy soul with hoops of steel;
   1389        But do not dull thy palm with entertainment
   1390        Of each new-hatch'd, unfledged comrade. Beware
   1391        Of entrance to a quarrel, but being in,
   1392        Bear't that the opposed may beware of thee.
   1393        Give every man thy ear, but few thy voice;
   1394        Take each man's censure, but reserve thy judgment.
   1395        Costly thy habit as thy purse can buy,
   1396        But not express'd in fancy; rich, not gaudy;
   1397        For the apparel oft proclaims the man,
   1398        And they in France of the best rank and station
   1399        Are of a most select and generous chief in that.
   1400        Neither a borrower nor a lender be;
   1401        For loan oft loses both itself and friend,
   1402        And borrowing dulls the edge of husbandry.
   1403        This above all: to thine ownself be true,
   1404        And it must follow, as the night the day,
   1405        Thou canst not then be false to any man.
   1406        Farewell: my blessing season this in thee!
   1407 
   1408 LAERTES
   1409 
   1410        Most humbly do I take my leave, my lord.
   1411 
   1412 LORD POLONIUS
   1413 
   1414        The time invites you; go; your servants tend.
   1415 
   1416 LAERTES
   1417 
   1418        Farewell, Ophelia; and remember well
   1419        What I have said to you.
   1420 
   1421 OPHELIA
   1422 
   1423        'Tis in my memory lock'd,
   1424        And you yourself shall keep the key of it.
   1425 
   1426 LAERTES
   1427 
   1428        Farewell.
   1429 """
   1430 
   1431 COMPRESSED_BOGUS = b"this is not a valid lzma stream"
   1432 
   1433 COMPRESSED_XZ = (
   1434     b"\xfd7zXZ\x00\x00\x04\xe6\xd6\xb4F\x02\x00!\x01\x16\x00\x00\x00t/\xe5\xa3"
   1435     b"\xe0\x07\x80\x03\xdf]\x00\x05\x14\x07bX\x19\xcd\xddn\x98\x15\xe4\xb4\x9d"
   1436     b"o\x1d\xc4\xe5\n\x03\xcc2h\xc7\\\x86\xff\xf8\xe2\xfc\xe7\xd9\xfe6\xb8("
   1437     b"\xa8wd\xc2\"u.n\x1e\xc3\xf2\x8e\x8d\x8f\x02\x17/\xa6=\xf0\xa2\xdf/M\x89"
   1438     b"\xbe\xde\xa7\x1cz\x18-]\xd5\xef\x13\x8frZ\x15\x80\x8c\xf8\x8do\xfa\x12"
   1439     b"\x9b#z/\xef\xf0\xfaF\x01\x82\xa3M\x8e\xa1t\xca6 BF$\xe5Q\xa4\x98\xee\xde"
   1440     b"l\xe8\x7f\xf0\x9d,bn\x0b\x13\xd4\xa8\x81\xe4N\xc8\x86\x153\xf5x2\xa2O"
   1441     b"\x13@Q\xa1\x00/\xa5\xd0O\x97\xdco\xae\xf7z\xc4\xcdS\xb6t<\x16\xf2\x9cI#"
   1442     b"\x89ud\xc66Y\xd9\xee\xe6\xce\x12]\xe5\xf0\xaa\x96-Pe\xade:\x04\t\x1b\xf7"
   1443     b"\xdb7\n\x86\x1fp\xc8J\xba\xf4\xf0V\xa9\xdc\xf0\x02%G\xf9\xdf=?\x15\x1b"
   1444     b"\xe1(\xce\x82=\xd6I\xac3\x12\x0cR\xb7\xae\r\xb1i\x03\x95\x01\xbd\xbe\xfa"
   1445     b"\x02s\x01P\x9d\x96X\xb12j\xc8L\xa8\x84b\xf6\xc3\xd4c-H\x93oJl\xd0iQ\xe4k"
   1446     b"\x84\x0b\xc1\xb7\xbc\xb1\x17\x88\xb1\xca?@\xf6\x07\xea\xe6x\xf1H12P\x0f"
   1447     b"\x8a\xc9\xeauw\xe3\xbe\xaai\xa9W\xd0\x80\xcd#cb5\x99\xd8]\xa9d\x0c\xbd"
   1448     b"\xa2\xdcWl\xedUG\xbf\x89yF\xf77\x81v\xbd5\x98\xbeh8\x18W\x08\xf0\x1b\x99"
   1449     b"5:\x1a?rD\x96\xa1\x04\x0f\xae\xba\x85\xeb\x9d5@\xf5\x83\xd37\x83\x8ac"
   1450     b"\x06\xd4\x97i\xcdt\x16S\x82k\xf6K\x01vy\x88\x91\x9b6T\xdae\r\xfd]:k\xbal"
   1451     b"\xa9\xbba\xc34\xf9r\xeb}r\xdb\xc7\xdb*\x8f\x03z\xdc8h\xcc\xc9\xd3\xbcl"
   1452     b"\xa5-\xcb\xeaK\xa2\xc5\x15\xc0\xe3\xc1\x86Z\xfb\xebL\xe13\xcf\x9c\xe3"
   1453     b"\x1d\xc9\xed\xc2\x06\xcc\xce!\x92\xe5\xfe\x9c^\xa59w \x9bP\xa3PK\x08d"
   1454     b"\xf9\xe2Z}\xa7\xbf\xed\xeb%$\x0c\x82\xb8/\xb0\x01\xa9&,\xf7qh{Q\x96)\xf2"
   1455     b"q\x96\xc3\x80\xb4\x12\xb0\xba\xe6o\xf4!\xb4[\xd4\x8aw\x10\xf7t\x0c\xb3"
   1456     b"\xd9\xd5\xc3`^\x81\x11??\\\xa4\x99\x85R\xd4\x8e\x83\xc9\x1eX\xbfa\xf1"
   1457     b"\xac\xb0\xea\xea\xd7\xd0\xab\x18\xe2\xf2\xed\xe1\xb7\xc9\x18\xcbS\xe4>"
   1458     b"\xc9\x95H\xe8\xcb\t\r%\xeb\xc7$.o\xf1\xf3R\x17\x1db\xbb\xd8U\xa5^\xccS"
   1459     b"\x16\x01\x87\xf3/\x93\xd1\xf0v\xc0r\xd7\xcc\xa2Gkz\xca\x80\x0e\xfd\xd0"
   1460     b"\x8b\xbb\xd2Ix\xb3\x1ey\xca-0\xe3z^\xd6\xd6\x8f_\xf1\x9dP\x9fi\xa7\xd1"
   1461     b"\xe8\x90\x84\xdc\xbf\xcdky\x8e\xdc\x81\x7f\xa3\xb2+\xbf\x04\xef\xd8\\"
   1462     b"\xc4\xdf\xe1\xb0\x01\xe9\x93\xe3Y\xf1\x1dY\xe8h\x81\xcf\xf1w\xcc\xb4\xef"
   1463     b" \x8b|\x04\xea\x83ej\xbe\x1f\xd4z\x9c`\xd3\x1a\x92A\x06\xe5\x8f\xa9\x13"
   1464     b"\t\x9e=\xfa\x1c\xe5_\x9f%v\x1bo\x11ZO\xd8\xf4\t\xddM\x16-\x04\xfc\x18<\""
   1465     b"CM\xddg~b\xf6\xef\x8e\x0c\xd0\xde|\xa0'\x8a\x0c\xd6x\xae!J\xa6F\x88\x15u"
   1466     b"\x008\x17\xbc7y\xb3\xd8u\xac_\x85\x8d\xe7\xc1@\x9c\xecqc\xa3#\xad\xf1"
   1467     b"\x935\xb5)_\r\xec3]\x0fo]5\xd0my\x07\x9b\xee\x81\xb5\x0f\xcfK+\x00\xc0"
   1468     b"\xe4b\x10\xe4\x0c\x1a \x9b\xe0\x97t\xf6\xa1\x9e\x850\xba\x0c\x9a\x8d\xc8"
   1469     b"\x8f\x07\xd7\xae\xc8\xf9+i\xdc\xb9k\xb0>f\x19\xb8\r\xa8\xf8\x1f$\xa5{p"
   1470     b"\xc6\x880\xce\xdb\xcf\xca_\x86\xac\x88h6\x8bZ%'\xd0\n\xbf\x0f\x9c\"\xba"
   1471     b"\xe5\x86\x9f\x0f7X=mNX[\xcc\x19FU\xc9\x860\xbc\x90a+* \xae_$\x03\x1e\xd3"
   1472     b"\xcd_\xa0\x9c\xde\xaf46q\xa5\xc9\x92\xd7\xca\xe3`\x9d\x85}\xb4\xff\xb3"
   1473     b"\x83\xfb\xb6\xca\xae`\x0bw\x7f\xfc\xd8\xacVe\x19\xc8\x17\x0bZ\xad\x88"
   1474     b"\xeb#\x97\x03\x13\xb1d\x0f{\x0c\x04w\x07\r\x97\xbd\xd6\xc1\xc3B:\x95\x08"
   1475     b"^\x10V\xaeaH\x02\xd9\xe3\n\\\x01X\xf6\x9c\x8a\x06u#%\xbe*\xa1\x18v\x85"
   1476     b"\xec!\t4\x00\x00\x00\x00Vj?uLU\xf3\xa6\x00\x01\xfb\x07\x81\x0f\x00\x00tw"
   1477     b"\x99P\xb1\xc4g\xfb\x02\x00\x00\x00\x00\x04YZ"
   1478 )
   1479 
   1480 COMPRESSED_ALONE = (
   1481     b"]\x00\x00\x80\x00\xff\xff\xff\xff\xff\xff\xff\xff\x00\x05\x14\x07bX\x19"
   1482     b"\xcd\xddn\x98\x15\xe4\xb4\x9do\x1d\xc4\xe5\n\x03\xcc2h\xc7\\\x86\xff\xf8"
   1483     b"\xe2\xfc\xe7\xd9\xfe6\xb8(\xa8wd\xc2\"u.n\x1e\xc3\xf2\x8e\x8d\x8f\x02"
   1484     b"\x17/\xa6=\xf0\xa2\xdf/M\x89\xbe\xde\xa7\x1cz\x18-]\xd5\xef\x13\x8frZ"
   1485     b"\x15\x80\x8c\xf8\x8do\xfa\x12\x9b#z/\xef\xf0\xfaF\x01\x82\xa3M\x8e\xa1t"
   1486     b"\xca6 BF$\xe5Q\xa4\x98\xee\xdel\xe8\x7f\xf0\x9d,bn\x0b\x13\xd4\xa8\x81"
   1487     b"\xe4N\xc8\x86\x153\xf5x2\xa2O\x13@Q\xa1\x00/\xa5\xd0O\x97\xdco\xae\xf7z"
   1488     b"\xc4\xcdS\xb6t<\x16\xf2\x9cI#\x89ud\xc66Y\xd9\xee\xe6\xce\x12]\xe5\xf0"
   1489     b"\xaa\x96-Pe\xade:\x04\t\x1b\xf7\xdb7\n\x86\x1fp\xc8J\xba\xf4\xf0V\xa9"
   1490     b"\xdc\xf0\x02%G\xf9\xdf=?\x15\x1b\xe1(\xce\x82=\xd6I\xac3\x12\x0cR\xb7"
   1491     b"\xae\r\xb1i\x03\x95\x01\xbd\xbe\xfa\x02s\x01P\x9d\x96X\xb12j\xc8L\xa8"
   1492     b"\x84b\xf8\x1epl\xeajr\xd1=\t\x03\xdd\x13\x1b3!E\xf9vV\xdaF\xf3\xd7\xb4"
   1493     b"\x0c\xa9P~\xec\xdeE\xe37\xf6\x1d\xc6\xbb\xddc%\xb6\x0fI\x07\xf0;\xaf\xe7"
   1494     b"\xa0\x8b\xa7Z\x99(\xe9\xe2\xf0o\x18>`\xe1\xaa\xa8\xd9\xa1\xb2}\xe7\x8d"
   1495     b"\x834T\xb6\xef\xc1\xde\xe3\x98\xbcD\x03MA@\xd8\xed\xdc\xc8\x93\x03\x1a"
   1496     b"\x93\x0b\x7f\x94\x12\x0b\x02Sa\x18\xc9\xc5\x9bTJE}\xf6\xc8g\x17#ZV\x01"
   1497     b"\xc9\x9dc\x83\x0e>0\x16\x90S\xb8/\x03y_\x18\xfa(\xd7\x0br\xa2\xb0\xba?"
   1498     b"\x8c\xe6\x83@\x84\xdf\x02:\xc5z\x9e\xa6\x84\xc9\xf5BeyX\x83\x1a\xf1 :\t"
   1499     b"\xf7\x19\xfexD\\&G\xf3\x85Y\xa2J\xf9\x0bv{\x89\xf6\xe7)A\xaf\x04o\x00"
   1500     b"\x075\xd3\xe0\x7f\x97\x98F\x0f?v\x93\xedVtTf\xb5\x97\x83\xed\x19\xd7\x1a"
   1501     b"'k\xd7\xd9\xc5\\Y\xd1\xdc\x07\x15|w\xbc\xacd\x87\x08d\xec\xa7\xf6\x82"
   1502     b"\xfc\xb3\x93\xeb\xb9 \x8d\xbc ,\xb3X\xb0\xd2s\xd7\xd1\xffv\x05\xdf}\xa2"
   1503     b"\x96\xfb%\n\xdf\xa2\x7f\x08.\xa16\n\xe0\x19\x93\x7fh\n\x1c\x8c\x0f \x11"
   1504     b"\xc6Bl\x95\x19U}\xe4s\xb5\x10H\xea\x86pB\xe88\x95\xbe\x8cZ\xdb\xe4\x94A"
   1505     b"\x92\xb9;z\xaa\xa7{\x1c5!\xc0\xaf\xc1A\xf9\xda\xf0$\xb0\x02qg\xc8\xc7/|"
   1506     b"\xafr\x99^\x91\x88\xbf\x03\xd9=\xd7n\xda6{>8\n\xc7:\xa9'\xba.\x0b\xe2"
   1507     b"\xb5\x1d\x0e\n\x9a\x8e\x06\x8f:\xdd\x82'[\xc3\"wD$\xa7w\xecq\x8c,1\x93"
   1508     b"\xd0,\xae2w\x93\x12$Jd\x19mg\x02\x93\x9cA\x95\x9d&\xca8i\x9c\xb0;\xe7NQ"
   1509     b"\x1frh\x8beL;\xb0m\xee\x07Q\x9b\xc6\xd8\x03\xb5\xdeN\xd4\xfe\x98\xd0\xdc"
   1510     b"\x1a[\x04\xde\x1a\xf6\x91j\xf8EOli\x8eB^\x1d\x82\x07\xb2\xb5R]\xb7\xd7"
   1511     b"\xe9\xa6\xc3.\xfb\xf0-\xb4e\x9b\xde\x03\x88\xc6\xc1iN\x0e\x84wbQ\xdf~"
   1512     b"\xe9\xa4\x884\x96kM\xbc)T\xf3\x89\x97\x0f\x143\xe7)\xa0\xb3B\x00\xa8\xaf"
   1513     b"\x82^\xcb\xc7..\xdb\xc7\t\x9dH\xee5\xe9#\xe6NV\x94\xcb$Kk\xe3\x7f\r\xe3t"
   1514     b"\x12\xcf'\xefR\x8b\xf42\xcf-LH\xac\xe5\x1f0~?SO\xeb\xc1E\x1a\x1c]\xf2"
   1515     b"\xc4<\x11\x02\x10Z0a*?\xe4r\xff\xfb\xff\xf6\x14nG\xead^\xd6\xef8\xb6uEI"
   1516     b"\x99\nV\xe2\xb3\x95\x8e\x83\xf6i!\xb5&1F\xb1DP\xf4 SO3D!w\x99_G\x7f+\x90"
   1517     b".\xab\xbb]\x91>\xc9#h;\x0f5J\x91K\xf4^-[\x9e\x8a\\\x94\xca\xaf\xf6\x19"
   1518     b"\xd4\xa1\x9b\xc4\xb8p\xa1\xae\x15\xe9r\x84\xe0\xcar.l []\x8b\xaf+0\xf2g"
   1519     b"\x01aKY\xdfI\xcf,\n\xe8\xf0\xe7V\x80_#\xb2\xf2\xa9\x06\x8c>w\xe2W,\xf4"
   1520     b"\x8c\r\xf963\xf5J\xcc2\x05=kT\xeaUti\xe5_\xce\x1b\xfa\x8dl\x02h\xef\xa8"
   1521     b"\xfbf\x7f\xff\xf0\x19\xeax"
   1522 )
   1523 
   1524 FILTERS_RAW_1 = [{"id": lzma.FILTER_LZMA2, "preset": 3}]
   1525 COMPRESSED_RAW_1 = (
   1526     b"\xe0\x07\x80\x03\xfd]\x00\x05\x14\x07bX\x19\xcd\xddn\x96cyq\xa1\xdd\xee"
   1527     b"\xf8\xfam\xe3'\x88\xd3\xff\xe4\x9e \xceQ\x91\xa4\x14I\xf6\xb9\x9dVL8\x15"
   1528     b"_\x0e\x12\xc3\xeb\xbc\xa5\xcd\nW\x1d$=R;\x1d\xf8k8\t\xb1{\xd4\xc5+\x9d"
   1529     b"\x87c\xe5\xef\x98\xb4\xd7S3\xcd\xcc\xd2\xed\xa4\x0em\xe5\xf4\xdd\xd0b"
   1530     b"\xbe4*\xaa\x0b\xc5\x08\x10\x85+\x81.\x17\xaf9\xc9b\xeaZrA\xe20\x7fs\"r"
   1531     b"\xdaG\x81\xde\x90cu\xa5\xdb\xa9.A\x08l\xb0<\xf6\x03\xddOi\xd0\xc5\xb4"
   1532     b"\xec\xecg4t6\"\xa6\xb8o\xb5?\x18^}\xb6}\x03[:\xeb\x03\xa9\n[\x89l\x19g"
   1533     b"\x16\xc82\xed\x0b\xfb\x86n\xa2\x857@\x93\xcd6T\xc3u\xb0\t\xf9\x1b\x918"
   1534     b"\xfc[\x1b\x1e4\xb3\x14\x06PCV\xa8\"\xf5\x81x~\xe9\xb5N\x9cK\x9f\xc6\xc3%"
   1535     b"\xc8k:{6\xe7\xf7\xbd\x05\x02\xb4\xc4\xc3\xd3\xfd\xc3\xa8\\\xfc@\xb1F_"
   1536     b"\xc8\x90\xd9sU\x98\xad8\x05\x07\xde7J\x8bM\xd0\xb3;X\xec\x87\xef\xae\xb3"
   1537     b"eO,\xb1z,d\x11y\xeejlB\x02\x1d\xf28\x1f#\x896\xce\x0b\xf0\xf5\xa9PK\x0f"
   1538     b"\xb3\x13P\xd8\x88\xd2\xa1\x08\x04C?\xdb\x94_\x9a\"\xe9\xe3e\x1d\xde\x9b"
   1539     b"\xa1\xe8>H\x98\x10;\xc5\x03#\xb5\x9d4\x01\xe7\xc5\xba%v\xa49\x97A\xe0\""
   1540     b"\x8c\xc22\xe3i\xc1\x9d\xab3\xdf\xbe\xfdDm7\x1b\x9d\xab\xb5\x15o:J\x92"
   1541     b"\xdb\x816\x17\xc2O\x99\x1b\x0e\x8d\xf3\tQ\xed\x8e\x95S/\x16M\xb2S\x04"
   1542     b"\x0f\xc3J\xc6\xc7\xe4\xcb\xc5\xf4\xe7d\x14\xe4=^B\xfb\xd3E\xd3\x1e\xcd"
   1543     b"\x91\xa5\xd0G\x8f.\xf6\xf9\x0bb&\xd9\x9f\xc2\xfdj\xa2\x9e\xc4\\\x0e\x1dC"
   1544     b"v\xe8\xd2\x8a?^H\xec\xae\xeb>\xfe\xb8\xab\xd4IqY\x8c\xd4K7\x11\xf4D\xd0W"
   1545     b"\xa5\xbe\xeaO\xbf\xd0\x04\xfdl\x10\xae5\xd4U\x19\x06\xf9{\xaa\xe0\x81"
   1546     b"\x0f\xcf\xa3k{\x95\xbd\x19\xa2\xf8\xe4\xa3\x08O*\xf1\xf1B-\xc7(\x0eR\xfd"
   1547     b"@E\x9f\xd3\x1e:\xfdV\xb7\x04Y\x94\xeb]\x83\xc4\xa5\xd7\xc0gX\x98\xcf\x0f"
   1548     b"\xcd3\x00]n\x17\xec\xbd\xa3Y\x86\xc5\xf3u\xf6*\xbdT\xedA$A\xd9A\xe7\x98"
   1549     b"\xef\x14\x02\x9a\xfdiw\xec\xa0\x87\x11\xd9%\xc5\xeb\x8a=\xae\xc0\xc4\xc6"
   1550     b"D\x80\x8f\xa8\xd1\xbbq\xb2\xc0\xa0\xf5Cqp\xeeL\xe3\xe5\xdc \x84\"\xe9"
   1551     b"\x80t\x83\x05\xba\xf1\xc5~\x93\xc9\xf0\x01c\xceix\x9d\xed\xc5)l\x16)\xd1"
   1552     b"\x03@l\x04\x7f\x87\xa5yn\x1b\x01D\xaa:\xd2\x96\xb4\xb3?\xb0\xf9\xce\x07"
   1553     b"\xeb\x81\x00\xe4\xc3\xf5%_\xae\xd4\xf9\xeb\xe2\rh\xb2#\xd67Q\x16D\x82hn"
   1554     b"\xd1\xa3_?q\xf0\xe2\xac\xf317\x9e\xd0_\x83|\xf1\xca\xb7\x95S\xabW\x12"
   1555     b"\xff\xddt\xf69L\x01\xf2|\xdaW\xda\xees\x98L\x18\xb8_\xe8$\x82\xea\xd6"
   1556     b"\xd1F\xd4\x0b\xcdk\x01vf\x88h\xc3\xae\xb91\xc7Q\x9f\xa5G\xd9\xcc\x1f\xe3"
   1557     b"5\xb1\xdcy\x7fI\x8bcw\x8e\x10rIp\x02:\x19p_\xc8v\xcea\"\xc1\xd9\x91\x03"
   1558     b"\xbfe\xbe\xa6\xb3\xa8\x14\x18\xc3\xabH*m}\xc2\xc1\x9a}>l%\xce\x84\x99"
   1559     b"\xb3d\xaf\xd3\x82\x15\xdf\xc1\xfc5fOg\x9b\xfc\x8e^&\t@\xce\x9f\x06J\xb8"
   1560     b"\xb5\x86\x1d\xda{\x9f\xae\xb0\xff\x02\x81r\x92z\x8cM\xb7ho\xc9^\x9c\xb6"
   1561     b"\x9c\xae\xd1\xc9\xf4\xdfU7\xd6\\!\xea\x0b\x94k\xb9Ud~\x98\xe7\x86\x8az"
   1562     b"\x10;\xe3\x1d\xe5PG\xf8\xa4\x12\x05w\x98^\xc4\xb1\xbb\xfb\xcf\xe0\x7f"
   1563     b"\x033Sf\x0c \xb1\xf6@\x94\xe5\xa3\xb2\xa7\x10\x9a\xc0\x14\xc3s\xb5xRD"
   1564     b"\xf4`W\xd9\xe5\xd3\xcf\x91\rTZ-X\xbe\xbf\xb5\xe2\xee|\x1a\xbf\xfb\x08"
   1565     b"\x91\xe1\xfc\x9a\x18\xa3\x8b\xd6^\x89\xf5[\xef\x87\xd1\x06\x1c7\xd6\xa2"
   1566     b"\t\tQ5/@S\xc05\xd2VhAK\x03VC\r\x9b\x93\xd6M\xf1xO\xaaO\xed\xb9<\x0c\xdae"
   1567     b"*\xd0\x07Hk6\x9fG+\xa1)\xcd\x9cl\x87\xdb\xe1\xe7\xefK}\x875\xab\xa0\x19u"
   1568     b"\xf6*F\xb32\x00\x00\x00"
   1569 )
   1570 
   1571 FILTERS_RAW_2 = [{"id": lzma.FILTER_DELTA, "dist": 2},
   1572                  {"id": lzma.FILTER_LZMA2,
   1573                   "preset": lzma.PRESET_DEFAULT | lzma.PRESET_EXTREME}]
   1574 COMPRESSED_RAW_2 = (
   1575     b"\xe0\x07\x80\x05\x91]\x00\x05\x14\x06-\xd4\xa8d?\xef\xbe\xafH\xee\x042"
   1576     b"\xcb.\xb5g\x8f\xfb\x14\xab\xa5\x9f\x025z\xa4\xdd\xd8\t[}W\xf8\x0c\x1dmH"
   1577     b"\xfa\x05\xfcg\xba\xe5\x01Q\x0b\x83R\xb6A\x885\xc0\xba\xee\n\x1cv~\xde:o"
   1578     b"\x06:J\xa7\x11Cc\xea\xf7\xe5*o\xf7\x83\\l\xbdE\x19\x1f\r\xa8\x10\xb42"
   1579     b"\x0caU{\xd7\xb8w\xdc\xbe\x1b\xfc8\xb4\xcc\xd38\\\xf6\x13\xf6\xe7\x98\xfa"
   1580     b"\xc7[\x17_9\x86%\xa8\xf8\xaa\xb8\x8dfs#\x1e=\xed<\x92\x10\\t\xff\x86\xfb"
   1581     b"=\x9e7\x18\x1dft\\\xb5\x01\x95Q\xc5\x19\xb38\xe0\xd4\xaa\x07\xc3\x7f\xd8"
   1582     b"\xa2\x00>-\xd3\x8e\xa1#\xfa\x83ArAm\xdbJ~\x93\xa3B\x82\xe0\xc7\xcc(\x08`"
   1583     b"WK\xad\x1b\x94kaj\x04 \xde\xfc\xe1\xed\xb0\x82\x91\xefS\x84%\x86\xfbi"
   1584     b"\x99X\xf1B\xe7\x90;E\xfde\x98\xda\xca\xd6T\xb4bg\xa4\n\x9aj\xd1\x83\x9e]"
   1585     b"\"\x7fM\xb5\x0fr\xd2\\\xa5j~P\x10GH\xbfN*Z\x10.\x81\tpE\x8a\x08\xbe1\xbd"
   1586     b"\xcd\xa9\xe1\x8d\x1f\x04\xf9\x0eH\xb9\xae\xd6\xc3\xc1\xa5\xa9\x95P\xdc~"
   1587     b"\xff\x01\x930\xa9\x04\xf6\x03\xfe\xb5JK\xc3]\xdd9\xb1\xd3\xd7F\xf5\xd1"
   1588     b"\x1e\xa0\x1c_\xed[\x0c\xae\xd4\x8b\x946\xeb\xbf\xbb\xe3$kS{\xb5\x80,f:Sj"
   1589     b"\x0f\x08z\x1c\xf5\xe8\xe6\xae\x98\xb0Q~r\x0f\xb0\x05?\xb6\x90\x19\x02&"
   1590     b"\xcb\x80\t\xc4\xea\x9c|x\xce\x10\x9c\xc5|\xcbdhh+\x0c'\xc5\x81\xc33\xb5"
   1591     b"\x14q\xd6\xc5\xe3`Z#\xdc\x8a\xab\xdd\xea\x08\xc2I\xe7\x02l{\xec\x196\x06"
   1592     b"\x91\x8d\xdc\xd5\xb3x\xe1hz%\xd1\xf8\xa5\xdd\x98!\x8c\x1c\xc1\x17RUa\xbb"
   1593     b"\x95\x0f\xe4X\xea1\x0c\xf1=R\xbe\xc60\xe3\xa4\x9a\x90bd\x97$]B\x01\xdd"
   1594     b"\x1f\xe3h2c\x1e\xa0L`4\xc6x\xa3Z\x8a\r\x14]T^\xd8\x89\x1b\x92\r;\xedY"
   1595     b"\x0c\xef\x8d9z\xf3o\xb6)f\xa9]$n\rp\x93\xd0\x10\xa4\x08\xb8\xb2\x8b\xb6"
   1596     b"\x8f\x80\xae;\xdcQ\xf1\xfa\x9a\x06\x8e\xa5\x0e\x8cK\x9c @\xaa:UcX\n!\xc6"
   1597     b"\x02\x12\xcb\x1b\"=\x16.\x1f\x176\xf2g=\xe1Wn\xe9\xe1\xd4\xf1O\xad\x15"
   1598     b"\x86\xe9\xa3T\xaf\xa9\xd7D\xb5\xd1W3pnt\x11\xc7VOj\xb7M\xc4i\xa1\xf1$3"
   1599     b"\xbb\xdc\x8af\xb0\xc5Y\r\xd1\xfb\xf2\xe7K\xe6\xc5hwO\xfe\x8c2^&\x07\xd5"
   1600     b"\x1fV\x19\xfd\r\x14\xd2i=yZ\xe6o\xaf\xc6\xb6\x92\x9d\xc4\r\xb3\xafw\xac%"
   1601     b"\xcfc\x1a\xf1`]\xf2\x1a\x9e\x808\xedm\xedQ\xb2\xfe\xe4h`[q\xae\xe0\x0f"
   1602     b"\xba0g\xb6\"N\xc3\xfb\xcfR\x11\xc5\x18)(\xc40\\\xa3\x02\xd9G!\xce\x1b"
   1603     b"\xc1\x96x\xb5\xc8z\x1f\x01\xb4\xaf\xde\xc2\xcd\x07\xe7H\xb3y\xa8M\n\\A\t"
   1604     b"ar\xddM\x8b\x9a\xea\x84\x9b!\xf1\x8d\xb1\xf1~\x1e\r\xa5H\xba\xf1\x84o"
   1605     b"\xda\x87\x01h\xe9\xa2\xbe\xbeqN\x9d\x84\x0b!WG\xda\xa1\xa5A\xb7\xc7`j"
   1606     b"\x15\xf2\xe9\xdd?\x015B\xd2~E\x06\x11\xe0\x91!\x05^\x80\xdd\xa8y\x15}"
   1607     b"\xa1)\xb1)\x81\x18\xf4\xf4\xf8\xc0\xefD\xe3\xdb2f\x1e\x12\xabu\xc9\x97"
   1608     b"\xcd\x1e\xa7\x0c\x02x4_6\x03\xc4$t\xf39\x94\x1d=\xcb\xbfv\\\xf5\xa3\x1d"
   1609     b"\x9d8jk\x95\x13)ff\xf9n\xc4\xa9\xe3\x01\xb8\xda\xfb\xab\xdfM\x99\xfb\x05"
   1610     b"\xe0\xe9\xb0I\xf4E\xab\xe2\x15\xa3\x035\xe7\xdeT\xee\x82p\xb4\x88\xd3"
   1611     b"\x893\x9c/\xc0\xd6\x8fou;\xf6\x95PR\xa9\xb2\xc1\xefFj\xe2\xa7$\xf7h\xf1"
   1612     b"\xdfK(\xc9c\xba7\xe8\xe3)\xdd\xb2,\x83\xfb\x84\x18.y\x18Qi\x88\xf8`h-"
   1613     b"\xef\xd5\xed\x8c\t\xd8\xc3^\x0f\x00\xb7\xd0[!\xafM\x9b\xd7.\x07\xd8\xfb"
   1614     b"\xd9\xe2-S+\xaa8,\xa0\x03\x1b \xea\xa8\x00\xc3\xab~\xd0$e\xa5\x7f\xf7"
   1615     b"\x95P]\x12\x19i\xd9\x7fo\x0c\xd8g^\rE\xa5\x80\x18\xc5\x01\x80\xaek`\xff~"
   1616     b"\xb6y\xe7+\xe5\x11^D\xa7\x85\x18\"!\xd6\xd2\xa7\xf4\x1eT\xdb\x02\xe15"
   1617     b"\x02Y\xbc\x174Z\xe7\x9cH\x1c\xbf\x0f\xc6\xe9f]\xcf\x8cx\xbc\xe5\x15\x94"
   1618     b"\xfc3\xbc\xa7TUH\xf1\x84\x1b\xf7\xa9y\xc07\x84\xf8X\xd8\xef\xfc \x1c\xd8"
   1619     b"( /\xf2\xb7\xec\xc1\\\x8c\xf6\x95\xa1\x03J\x83vP8\xe1\xe3\xbb~\xc24kA"
   1620     b"\x98y\xa1\xf2P\xe9\x9d\xc9J\xf8N\x99\xb4\xceaO\xde\x16\x1e\xc2\x19\xa7"
   1621     b"\x03\xd2\xe0\x8f:\x15\xf3\x84\x9e\xee\xe6e\xb8\x02q\xc7AC\x1emw\xfd\t"
   1622     b"\x9a\x1eu\xc1\xa9\xcaCwUP\x00\xa5\xf78L4w!\x91L2 \x87\xd0\xf2\x06\x81j"
   1623     b"\x80;\x03V\x06\x87\x92\xcb\x90lv@E\x8d\x8d\xa5\xa6\xe7Z[\xdf\xd6E\x03`>"
   1624     b"\x8f\xde\xa1bZ\x84\xd0\xa9`\x05\x0e{\x80;\xe3\xbef\x8d\x1d\xebk1.\xe3"
   1625     b"\xe9N\x15\xf7\xd4(\xfa\xbb\x15\xbdu\xf7\x7f\x86\xae!\x03L\x1d\xb5\xc1"
   1626     b"\xb9\x11\xdb\xd0\x93\xe4\x02\xe1\xd2\xcbBjc_\xe8}d\xdb\xc3\xa0Y\xbe\xc9/"
   1627     b"\x95\x01\xa3,\xe6bl@\x01\xdbp\xc2\xce\x14\x168\xc2q\xe3uH\x89X\xa4\xa9"
   1628     b"\x19\x1d\xc1}\x7fOX\x19\x9f\xdd\xbe\x85\x83\xff\x96\x1ee\x82O`CF=K\xeb$I"
   1629     b"\x17_\xefX\x8bJ'v\xde\x1f+\xd9.v\xf8Tv\x17\xf2\x9f5\x19\xe1\xb9\x91\xa8S"
   1630     b"\x86\xbd\x1a\"(\xa5x\x8dC\x03X\x81\x91\xa8\x11\xc4pS\x13\xbc\xf2'J\xae!"
   1631     b"\xef\xef\x84G\t\x8d\xc4\x10\x132\x00oS\x9e\xe0\xe4d\x8f\xb8y\xac\xa6\x9f"
   1632     b",\xb8f\x87\r\xdf\x9eE\x0f\xe1\xd0\\L\x00\xb2\xe1h\x84\xef}\x98\xa8\x11"
   1633     b"\xccW#\\\x83\x7fo\xbbz\x8f\x00"
   1634 )
   1635 
   1636 FILTERS_RAW_3 = [{"id": lzma.FILTER_IA64, "start_offset": 0x100},
   1637                  {"id": lzma.FILTER_LZMA2}]
   1638 COMPRESSED_RAW_3 = (
   1639     b"\xe0\x07\x80\x03\xdf]\x00\x05\x14\x07bX\x19\xcd\xddn\x98\x15\xe4\xb4\x9d"
   1640     b"o\x1d\xc4\xe5\n\x03\xcc2h\xc7\\\x86\xff\xf8\xe2\xfc\xe7\xd9\xfe6\xb8("
   1641     b"\xa8wd\xc2\"u.n\x1e\xc3\xf2\x8e\x8d\x8f\x02\x17/\xa6=\xf0\xa2\xdf/M\x89"
   1642     b"\xbe\xde\xa7\x1cz\x18-]\xd5\xef\x13\x8frZ\x15\x80\x8c\xf8\x8do\xfa\x12"
   1643     b"\x9b#z/\xef\xf0\xfaF\x01\x82\xa3M\x8e\xa1t\xca6 BF$\xe5Q\xa4\x98\xee\xde"
   1644     b"l\xe8\x7f\xf0\x9d,bn\x0b\x13\xd4\xa8\x81\xe4N\xc8\x86\x153\xf5x2\xa2O"
   1645     b"\x13@Q\xa1\x00/\xa5\xd0O\x97\xdco\xae\xf7z\xc4\xcdS\xb6t<\x16\xf2\x9cI#"
   1646     b"\x89ud\xc66Y\xd9\xee\xe6\xce\x12]\xe5\xf0\xaa\x96-Pe\xade:\x04\t\x1b\xf7"
   1647     b"\xdb7\n\x86\x1fp\xc8J\xba\xf4\xf0V\xa9\xdc\xf0\x02%G\xf9\xdf=?\x15\x1b"
   1648     b"\xe1(\xce\x82=\xd6I\xac3\x12\x0cR\xb7\xae\r\xb1i\x03\x95\x01\xbd\xbe\xfa"
   1649     b"\x02s\x01P\x9d\x96X\xb12j\xc8L\xa8\x84b\xf6\xc3\xd4c-H\x93oJl\xd0iQ\xe4k"
   1650     b"\x84\x0b\xc1\xb7\xbc\xb1\x17\x88\xb1\xca?@\xf6\x07\xea\xe6x\xf1H12P\x0f"
   1651     b"\x8a\xc9\xeauw\xe3\xbe\xaai\xa9W\xd0\x80\xcd#cb5\x99\xd8]\xa9d\x0c\xbd"
   1652     b"\xa2\xdcWl\xedUG\xbf\x89yF\xf77\x81v\xbd5\x98\xbeh8\x18W\x08\xf0\x1b\x99"
   1653     b"5:\x1a?rD\x96\xa1\x04\x0f\xae\xba\x85\xeb\x9d5@\xf5\x83\xd37\x83\x8ac"
   1654     b"\x06\xd4\x97i\xcdt\x16S\x82k\xf6K\x01vy\x88\x91\x9b6T\xdae\r\xfd]:k\xbal"
   1655     b"\xa9\xbba\xc34\xf9r\xeb}r\xdb\xc7\xdb*\x8f\x03z\xdc8h\xcc\xc9\xd3\xbcl"
   1656     b"\xa5-\xcb\xeaK\xa2\xc5\x15\xc0\xe3\xc1\x86Z\xfb\xebL\xe13\xcf\x9c\xe3"
   1657     b"\x1d\xc9\xed\xc2\x06\xcc\xce!\x92\xe5\xfe\x9c^\xa59w \x9bP\xa3PK\x08d"
   1658     b"\xf9\xe2Z}\xa7\xbf\xed\xeb%$\x0c\x82\xb8/\xb0\x01\xa9&,\xf7qh{Q\x96)\xf2"
   1659     b"q\x96\xc3\x80\xb4\x12\xb0\xba\xe6o\xf4!\xb4[\xd4\x8aw\x10\xf7t\x0c\xb3"
   1660     b"\xd9\xd5\xc3`^\x81\x11??\\\xa4\x99\x85R\xd4\x8e\x83\xc9\x1eX\xbfa\xf1"
   1661     b"\xac\xb0\xea\xea\xd7\xd0\xab\x18\xe2\xf2\xed\xe1\xb7\xc9\x18\xcbS\xe4>"
   1662     b"\xc9\x95H\xe8\xcb\t\r%\xeb\xc7$.o\xf1\xf3R\x17\x1db\xbb\xd8U\xa5^\xccS"
   1663     b"\x16\x01\x87\xf3/\x93\xd1\xf0v\xc0r\xd7\xcc\xa2Gkz\xca\x80\x0e\xfd\xd0"
   1664     b"\x8b\xbb\xd2Ix\xb3\x1ey\xca-0\xe3z^\xd6\xd6\x8f_\xf1\x9dP\x9fi\xa7\xd1"
   1665     b"\xe8\x90\x84\xdc\xbf\xcdky\x8e\xdc\x81\x7f\xa3\xb2+\xbf\x04\xef\xd8\\"
   1666     b"\xc4\xdf\xe1\xb0\x01\xe9\x93\xe3Y\xf1\x1dY\xe8h\x81\xcf\xf1w\xcc\xb4\xef"
   1667     b" \x8b|\x04\xea\x83ej\xbe\x1f\xd4z\x9c`\xd3\x1a\x92A\x06\xe5\x8f\xa9\x13"
   1668     b"\t\x9e=\xfa\x1c\xe5_\x9f%v\x1bo\x11ZO\xd8\xf4\t\xddM\x16-\x04\xfc\x18<\""
   1669     b"CM\xddg~b\xf6\xef\x8e\x0c\xd0\xde|\xa0'\x8a\x0c\xd6x\xae!J\xa6F\x88\x15u"
   1670     b"\x008\x17\xbc7y\xb3\xd8u\xac_\x85\x8d\xe7\xc1@\x9c\xecqc\xa3#\xad\xf1"
   1671     b"\x935\xb5)_\r\xec3]\x0fo]5\xd0my\x07\x9b\xee\x81\xb5\x0f\xcfK+\x00\xc0"
   1672     b"\xe4b\x10\xe4\x0c\x1a \x9b\xe0\x97t\xf6\xa1\x9e\x850\xba\x0c\x9a\x8d\xc8"
   1673     b"\x8f\x07\xd7\xae\xc8\xf9+i\xdc\xb9k\xb0>f\x19\xb8\r\xa8\xf8\x1f$\xa5{p"
   1674     b"\xc6\x880\xce\xdb\xcf\xca_\x86\xac\x88h6\x8bZ%'\xd0\n\xbf\x0f\x9c\"\xba"
   1675     b"\xe5\x86\x9f\x0f7X=mNX[\xcc\x19FU\xc9\x860\xbc\x90a+* \xae_$\x03\x1e\xd3"
   1676     b"\xcd_\xa0\x9c\xde\xaf46q\xa5\xc9\x92\xd7\xca\xe3`\x9d\x85}\xb4\xff\xb3"
   1677     b"\x83\xfb\xb6\xca\xae`\x0bw\x7f\xfc\xd8\xacVe\x19\xc8\x17\x0bZ\xad\x88"
   1678     b"\xeb#\x97\x03\x13\xb1d\x0f{\x0c\x04w\x07\r\x97\xbd\xd6\xc1\xc3B:\x95\x08"
   1679     b"^\x10V\xaeaH\x02\xd9\xe3\n\\\x01X\xf6\x9c\x8a\x06u#%\xbe*\xa1\x18v\x85"
   1680     b"\xec!\t4\x00\x00\x00"
   1681 )
   1682 
   1683 FILTERS_RAW_4 = [{"id": lzma.FILTER_DELTA, "dist": 4},
   1684                  {"id": lzma.FILTER_X86, "start_offset": 0x40},
   1685                  {"id": lzma.FILTER_LZMA2, "preset": 4, "lc": 2}]
   1686 COMPRESSED_RAW_4 = (
   1687     b"\xe0\x07\x80\x06\x0e\\\x00\x05\x14\x07bW\xaah\xdd\x10\xdc'\xd6\x90,\xc6v"
   1688     b"Jq \x14l\xb7\x83xB\x0b\x97f=&fx\xba\n>Tn\xbf\x8f\xfb\x1dF\xca\xc3v_\xca?"
   1689     b"\xfbV<\x92#\xd4w\xa6\x8a\xeb\xf6\x03\xc0\x01\x94\xd8\x9e\x13\x12\x98\xd1"
   1690     b"*\xfa]c\xe8\x1e~\xaf\xb5]Eg\xfb\x9e\x01\"8\xb2\x90\x06=~\xe9\x91W\xcd"
   1691     b"\xecD\x12\xc7\xfa\xe1\x91\x06\xc7\x99\xb9\xe3\x901\x87\x19u\x0f\x869\xff"
   1692     b"\xc1\xb0hw|\xb0\xdcl\xcck\xb16o7\x85\xee{Y_b\xbf\xbc$\xf3=\x8d\x8bw\xe5Z"
   1693     b"\x08@\xc4kmE\xad\xfb\xf6*\xd8\xad\xa1\xfb\xc5{\xdej,)\x1emB\x1f<\xaeca"
   1694     b"\x80(\xee\x07 \xdf\xe9\xf8\xeb\x0e-\x97\x86\x90c\xf9\xea'B\xf7`\xd7\xb0"
   1695     b"\x92\xbd\xa0\x82]\xbd\x0e\x0eB\x19\xdc\x96\xc6\x19\xd86D\xf0\xd5\x831"
   1696     b"\x03\xb7\x1c\xf7&5\x1a\x8f PZ&j\xf8\x98\x1bo\xcc\x86\x9bS\xd3\xa5\xcdu"
   1697     b"\xf9$\xcc\x97o\xe5V~\xfb\x97\xb5\x0b\x17\x9c\xfdxW\x10\xfep4\x80\xdaHDY"
   1698     b"\xfa)\xfet\xb5\"\xd4\xd3F\x81\xf4\x13\x1f\xec\xdf\xa5\x13\xfc\"\x91x\xb7"
   1699     b"\x99\xce\xc8\x92\n\xeb[\x10l*Y\xd8\xb1@\x06\xc8o\x8d7r\xebu\xfd5\x0e\x7f"
   1700     b"\xf1$U{\t}\x1fQ\xcfxN\x9d\x9fXX\xe9`\x83\xc1\x06\xf4\x87v-f\x11\xdb/\\"
   1701     b"\x06\xff\xd7)B\xf3g\x06\x88#2\x1eB244\x7f4q\t\xc893?mPX\x95\xa6a\xfb)d"
   1702     b"\x9b\xfc\x98\x9aj\x04\xae\x9b\x9d\x19w\xba\xf92\xfaA\x11\\\x17\x97C3\xa4"
   1703     b"\xbc!\x88\xcdo[\xec:\x030\x91.\x85\xe0@\\4\x16\x12\x9d\xcaJv\x97\xb04"
   1704     b"\xack\xcbkf\xa3ss\xfc\x16^\x8ce\x85a\xa5=&\xecr\xb3p\xd1E\xd5\x80y\xc7"
   1705     b"\xda\xf6\xfek\xbcT\xbfH\xee\x15o\xc5\x8c\x830\xec\x1d\x01\xae\x0c-e\\"
   1706     b"\x91\x90\x94\xb2\xf8\x88\x91\xe8\x0b\xae\xa7>\x98\xf6\x9ck\xd2\xc6\x08"
   1707     b"\xe6\xab\t\x98\xf2!\xa0\x8c^\xacqA\x99<\x1cEG\x97\xc8\xf1\xb6\xb9\x82"
   1708     b"\x8d\xf7\x08s\x98a\xff\xe3\xcc\x92\x0e\xd2\xb6U\xd7\xd9\x86\x7fa\xe5\x1c"
   1709     b"\x8dTG@\t\x1e\x0e7*\xfc\xde\xbc]6N\xf7\xf1\x84\x9e\x9f\xcf\xe9\x1e\xb5'"
   1710     b"\xf4<\xdf\x99sq\xd0\x9d\xbd\x99\x0b\xb4%p4\xbf{\xbb\x8a\xd2\x0b\xbc=M"
   1711     b"\x94H:\xf5\xa8\xd6\xa4\xc90\xc2D\xb9\xd3\xa8\xb0S\x87 `\xa2\xeb\xf3W\xce"
   1712     b" 7\xf9N#\r\xe6\xbe\t\x9d\xe7\x811\xf9\x10\xc1\xc2\x14\xf6\xfc\xcba\xb7"
   1713     b"\xb1\x7f\x95l\xe4\tjA\xec:\x10\xe5\xfe\xc2\\=D\xe2\x0c\x0b3]\xf7\xc1\xf7"
   1714     b"\xbceZ\xb1A\xea\x16\xe5\xfddgFQ\xed\xaf\x04\xa3\xd3\xf8\xa2q\x19B\xd4r"
   1715     b"\xc5\x0c\x9a\x14\x94\xea\x91\xc4o\xe4\xbb\xb4\x99\xf4@\xd1\xe6\x0c\xe3"
   1716     b"\xc6d\xa0Q\n\xf2/\xd8\xb8S5\x8a\x18:\xb5g\xac\x95D\xce\x17\x07\xd4z\xda"
   1717     b"\x90\xe65\x07\x19H!\t\xfdu\x16\x8e\x0eR\x19\xf4\x8cl\x0c\xf9Q\xf1\x80"
   1718     b"\xe3\xbf\xd7O\xf8\x8c\x18\x0b\x9c\xf1\x1fb\xe1\tR\xb2\xf1\xe1A\xea \xcf-"
   1719     b"IGE\xf1\x14\x98$\x83\x15\xc9\xd8j\xbf\x19\x0f\xd5\xd1\xaa\xb3\xf3\xa5I2s"
   1720     b"\x8d\x145\xca\xd5\xd93\x9c\xb8D0\xe6\xaa%\xd0\xc0P}JO^h\x8e\x08\xadlV."
   1721     b"\x18\x88\x13\x05o\xb0\x07\xeaw\xe0\xb6\xa4\xd5*\xe4r\xef\x07G+\xc1\xbei["
   1722     b"w\xe8\xab@_\xef\x15y\xe5\x12\xc9W\x1b.\xad\x85-\xc2\xf7\xe3mU6g\x8eSA"
   1723     b"\x01(\xd3\xdb\x16\x13=\xde\x92\xf9,D\xb8\x8a\xb2\xb4\xc9\xc3\xefnE\xe8\\"
   1724     b"\xa6\xe2Y\xd2\xcf\xcb\x8c\xb6\xd5\xe9\x1d\x1e\x9a\x8b~\xe2\xa6\rE\x84uV"
   1725     b"\xed\xc6\x99\xddm<\x10[\x0fu\x1f\xc1\x1d1\n\xcfw\xb2%!\xf0[\xce\x87\x83B"
   1726     b"\x08\xaa,\x08%d\xcef\x94\"\xd9g.\xc83\xcbXY+4\xec\x85qA\n\x1d=9\xf0*\xb1"
   1727     b"\x1f/\xf3s\xd61b\x7f@\xfb\x9d\xe3FQ\\\xbd\x82\x1e\x00\xf3\xce\xd3\xe1"
   1728     b"\xca,E\xfd7[\xab\xb6\xb7\xac!mA}\xbd\x9d3R5\x9cF\xabH\xeb\x92)cc\x13\xd0"
   1729     b"\xbd\xee\xe9n{\x1dIJB\xa5\xeb\x11\xe8`w&`\x8b}@Oxe\t\x8a\x07\x02\x95\xf2"
   1730     b"\xed\xda|\xb1e\xbe\xaa\xbbg\x19@\xe1Y\x878\x84\x0f\x8c\xe3\xc98\xf2\x9e"
   1731     b"\xd5N\xb5J\xef\xab!\xe2\x8dq\xe1\xe5q\xc5\xee\x11W\xb7\xe4k*\x027\xa0"
   1732     b"\xa3J\xf4\xd8m\xd0q\x94\xcb\x07\n:\xb6`.\xe4\x9c\x15+\xc0)\xde\x80X\xd4"
   1733     b"\xcfQm\x01\xc2cP\x1cA\x85'\xc9\xac\x8b\xe6\xb2)\xe6\x84t\x1c\x92\xe4Z"
   1734     b"\x1cR\xb0\x9e\x96\xd1\xfb\x1c\xa6\x8b\xcb`\x10\x12]\xf2gR\x9bFT\xe0\xc8H"
   1735     b"S\xfb\xac<\x04\xc7\xc1\xe8\xedP\xf4\x16\xdb\xc0\xd7e\xc2\x17J^\x1f\xab"
   1736     b"\xff[\x08\x19\xb4\xf5\xfb\x19\xb4\x04\xe5c~']\xcb\xc2A\xec\x90\xd0\xed"
   1737     b"\x06,\xc5K{\x86\x03\xb1\xcdMx\xdeQ\x8c3\xf9\x8a\xea=\x89\xaba\xd2\xc89a"
   1738     b"\xd72\xf0\xc3\x19\x8a\xdfs\xd4\xfd\xbb\x81b\xeaE\"\xd8\xf4d\x0cD\xf7IJ!"
   1739     b"\xe5d\xbbG\xe9\xcam\xaa\x0f_r\x95\x91NBq\xcaP\xce\xa7\xa9\xb5\x10\x94eP!"
   1740     b"|\x856\xcd\xbfIir\xb8e\x9bjP\x97q\xabwS7\x1a\x0ehM\xe7\xca\x86?\xdeP}y~"
   1741     b"\x0f\x95I\xfc\x13\xe1<Q\x1b\x868\x1d\x11\xdf\x94\xf4\x82>r\xa9k\x88\xcb"
   1742     b"\xfd\xc3v\xe2\xb9\x8a\x02\x8eq\x92I\xf8\xf6\xf1\x03s\x9b\xb8\xe3\"\xe3"
   1743     b"\xa9\xa5>D\xb8\x96;\xe7\x92\xd133\xe8\xdd'e\xc9.\xdc;\x17\x1f\xf5H\x13q"
   1744     b"\xa4W\x0c\xdb~\x98\x01\xeb\xdf\xe32\x13\x0f\xddx\n6\xa0\t\x10\xb6\xbb"
   1745     b"\xb0\xc3\x18\xb6;\x9fj[\xd9\xd5\xc9\x06\x8a\x87\xcd\xe5\xee\xfc\x9c-%@"
   1746     b"\xee\xe0\xeb\xd2\xe3\xe8\xfb\xc0\x122\\\xc7\xaf\xc2\xa1Oth\xb3\x8f\x82"
   1747     b"\xb3\x18\xa8\x07\xd5\xee_\xbe\xe0\x1cA\x1e_\r\x9a\xb0\x17W&\xa2D\x91\x94"
   1748     b"\x1a\xb2\xef\xf2\xdc\x85;X\xb0,\xeb>-7S\xe5\xca\x07)\x1fp\x7f\xcaQBL\xca"
   1749     b"\xf3\xb9d\xfc\xb5su\xb0\xc8\x95\x90\xeb*)\xa0v\xe4\x9a{FW\xf4l\xde\xcdj"
   1750     b"\x00"
   1751 )
   1752 
   1753 
   1754 def test_main():
   1755     run_unittest(
   1756         CompressorDecompressorTestCase,
   1757         CompressDecompressFunctionTestCase,
   1758         FileTestCase,
   1759         OpenTestCase,
   1760         MiscellaneousTestCase,
   1761     )
   1762 
   1763 if __name__ == "__main__":
   1764     test_main()
   1765