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