blob: 694ef6e48757b41416229dd7cacd4209ec7045c7 [file] [log] [blame]
Guido van Rossum7d9ea502003-02-03 20:45:52 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Hai Shia089d212020-07-06 17:15:08 +08003from test.support import import_helper
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00004import binascii
Zackery Spytzd2cbfff2018-06-27 12:04:51 -06005import copy
Serhiy Storchakad7a44152015-11-12 11:23:04 +02006import pickle
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00007import random
Antoine Pitrouf3d22752011-02-21 18:09:00 +00008import sys
Antoine Pitrou94190bb2011-10-04 10:22:36 +02009from test.support import bigmemtest, _1G, _4G
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000010
Hai Shia089d212020-07-06 17:15:08 +080011
12zlib = import_helper.import_module('zlib')
R. David Murraya21e4ca2009-03-31 23:16:50 +000013
Serhiy Storchaka43767632013-11-03 21:31:38 +020014requires_Compress_copy = unittest.skipUnless(
15 hasattr(zlib.compressobj(), "copy"),
16 'requires Compress.copy()')
17requires_Decompress_copy = unittest.skipUnless(
18 hasattr(zlib.decompressobj(), "copy"),
19 'requires Decompress.copy()')
20
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000021
Nadeem Vawda64d25dd2011-09-12 00:04:13 +020022class VersionTestCase(unittest.TestCase):
23
24 def test_library_version(self):
Nadeem Vawda131c7072012-01-25 23:16:50 +020025 # Test that the major version of the actual library in use matches the
26 # major version that we were compiled against. We can't guarantee that
27 # the minor versions will match (even on the machine on which the module
28 # was compiled), and the API is stable between minor versions, so
Nadeem Vawdad770fe42012-01-28 17:32:47 +020029 # testing only the major versions avoids spurious failures.
Nadeem Vawda131c7072012-01-25 23:16:50 +020030 self.assertEqual(zlib.ZLIB_RUNTIME_VERSION[0], zlib.ZLIB_VERSION[0])
Nadeem Vawda64d25dd2011-09-12 00:04:13 +020031
32
Guido van Rossum7d9ea502003-02-03 20:45:52 +000033class ChecksumTestCase(unittest.TestCase):
34 # checksum test cases
35 def test_crc32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000036 self.assertEqual(zlib.crc32(b""), zlib.crc32(b"", 0))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000037 self.assertTrue(zlib.crc32(b"abc", 0xffffffff))
Andrew M. Kuchlingfcfc8d52001-08-10 15:50:11 +000038
Guido van Rossum7d9ea502003-02-03 20:45:52 +000039 def test_crc32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000040 self.assertEqual(zlib.crc32(b"", 0), 0)
41 self.assertEqual(zlib.crc32(b"", 1), 1)
42 self.assertEqual(zlib.crc32(b"", 432), 432)
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000043
Guido van Rossum7d9ea502003-02-03 20:45:52 +000044 def test_adler32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000045 self.assertEqual(zlib.adler32(b""), zlib.adler32(b"", 1))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000046 self.assertTrue(zlib.adler32(b"abc", 0xffffffff))
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000047
Guido van Rossum7d9ea502003-02-03 20:45:52 +000048 def test_adler32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000049 self.assertEqual(zlib.adler32(b"", 0), 0)
50 self.assertEqual(zlib.adler32(b"", 1), 1)
51 self.assertEqual(zlib.adler32(b"", 432), 432)
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000052
Guido van Rossum7d9ea502003-02-03 20:45:52 +000053 def test_penguins(self):
Martin Panterb82032f2015-12-11 05:19:29 +000054 self.assertEqual(zlib.crc32(b"penguin", 0), 0x0e5c1a120)
55 self.assertEqual(zlib.crc32(b"penguin", 1), 0x43b6aa94)
56 self.assertEqual(zlib.adler32(b"penguin", 0), 0x0bcf02f6)
57 self.assertEqual(zlib.adler32(b"penguin", 1), 0x0bd602f7)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000058
Guido van Rossum776152b2007-05-22 22:44:07 +000059 self.assertEqual(zlib.crc32(b"penguin"), zlib.crc32(b"penguin", 0))
60 self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000061
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000062 def test_crc32_adler32_unsigned(self):
Antoine Pitrou77b338b2009-12-14 18:00:06 +000063 foo = b'abcdefghijklmnop'
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000064 # explicitly test signed behavior
Gregory P. Smith27275032008-03-20 06:20:09 +000065 self.assertEqual(zlib.crc32(foo), 2486878355)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000066 self.assertEqual(zlib.crc32(b'spam'), 1138425661)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000067 self.assertEqual(zlib.adler32(foo+foo), 3573550353)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000068 self.assertEqual(zlib.adler32(b'spam'), 72286642)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000069
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000070 def test_same_as_binascii_crc32(self):
Martin v. Löwis15b16a32008-12-02 06:00:15 +000071 foo = b'abcdefghijklmnop'
Gregory P. Smith27275032008-03-20 06:20:09 +000072 crc = 2486878355
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000073 self.assertEqual(binascii.crc32(foo), crc)
74 self.assertEqual(zlib.crc32(foo), crc)
Martin v. Löwis15b16a32008-12-02 06:00:15 +000075 self.assertEqual(binascii.crc32(b'spam'), zlib.crc32(b'spam'))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000076
77
Victor Stinner8c663fd2017-11-08 14:44:44 -080078# Issue #10276 - check that inputs >=4 GiB are handled correctly.
Antoine Pitrouf3d22752011-02-21 18:09:00 +000079class ChecksumBigBufferTestCase(unittest.TestCase):
80
Nadeem Vawdabc8c8172012-02-23 14:16:15 +020081 @bigmemtest(size=_4G + 4, memuse=1, dry_run=False)
82 def test_big_buffer(self, size):
Nadeem Vawdab063a482012-02-23 13:36:25 +020083 data = b"nyan" * (_1G + 1)
84 self.assertEqual(zlib.crc32(data), 1044521549)
85 self.assertEqual(zlib.adler32(data), 2256789997)
Antoine Pitrouf3d22752011-02-21 18:09:00 +000086
Christian Heimesb186d002008-03-18 15:15:01 +000087
Guido van Rossum7d9ea502003-02-03 20:45:52 +000088class ExceptionTestCase(unittest.TestCase):
89 # make sure we generate some expected errors
Guido van Rossum8ce8a782007-11-01 19:42:39 +000090 def test_badlevel(self):
91 # specifying compression level out of range causes an error
92 # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib
93 # accepts 0 too)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000094 self.assertRaises(zlib.error, zlib.compress, b'ERROR', 10)
95
96 def test_badargs(self):
97 self.assertRaises(TypeError, zlib.adler32)
98 self.assertRaises(TypeError, zlib.crc32)
99 self.assertRaises(TypeError, zlib.compress)
100 self.assertRaises(TypeError, zlib.decompress)
101 for arg in (42, None, '', 'abc', (), []):
102 self.assertRaises(TypeError, zlib.adler32, arg)
103 self.assertRaises(TypeError, zlib.crc32, arg)
104 self.assertRaises(TypeError, zlib.compress, arg)
105 self.assertRaises(TypeError, zlib.decompress, arg)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000106
107 def test_badcompressobj(self):
108 # verify failure on building compress object with bad params
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000109 self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000110 # specifying total bits too large causes an error
111 self.assertRaises(ValueError,
112 zlib.compressobj, 1, zlib.DEFLATED, zlib.MAX_WBITS + 1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000113
114 def test_baddecompressobj(self):
115 # verify failure on building decompress object with bad params
Antoine Pitrou90ee4df2010-04-06 17:23:13 +0000116 self.assertRaises(ValueError, zlib.decompressobj, -1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000117
Christian Heimes5e696852008-04-09 08:37:03 +0000118 def test_decompressobj_badflush(self):
119 # verify failure on calling decompressobj.flush with bad params
120 self.assertRaises(ValueError, zlib.decompressobj().flush, 0)
121 self.assertRaises(ValueError, zlib.decompressobj().flush, -1)
122
Martin Pantere99e9772015-11-20 08:13:35 +0000123 @support.cpython_only
124 def test_overflow(self):
125 with self.assertRaisesRegex(OverflowError, 'int too large'):
126 zlib.decompress(b'', 15, sys.maxsize + 1)
127 with self.assertRaisesRegex(OverflowError, 'int too large'):
Martin Panter84544c12016-07-23 03:02:07 +0000128 zlib.decompressobj().decompress(b'', sys.maxsize + 1)
129 with self.assertRaisesRegex(OverflowError, 'int too large'):
Martin Pantere99e9772015-11-20 08:13:35 +0000130 zlib.decompressobj().flush(sys.maxsize + 1)
131
Erlend Egeberg Aasland9746cda2021-04-30 16:04:57 +0200132 @support.cpython_only
133 def test_disallow_instantiation(self):
134 # Ensure that the type disallows instantiation (bpo-43916)
135 comp_type = type(zlib.compressobj())
136 decomp_type = type(zlib.decompressobj())
137 self.assertRaises(TypeError, comp_type)
138 self.assertRaises(TypeError, decomp_type)
139
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000140
Antoine Pitrou89562712010-05-07 17:04:02 +0000141class BaseCompressTestCase(object):
142 def check_big_compress_buffer(self, size, compress_func):
143 _1M = 1024 * 1024
Victor Stinner8c663fd2017-11-08 14:44:44 -0800144 # Generate 10 MiB worth of random, and expand it by repeating it.
Antoine Pitrou89562712010-05-07 17:04:02 +0000145 # The assumption is that zlib's memory is not big enough to exploit
146 # such spread out redundancy.
Victor Stinner87502dd2020-04-17 22:54:38 +0200147 data = random.randbytes(_1M * 10)
Antoine Pitrou89562712010-05-07 17:04:02 +0000148 data = data * (size // len(data) + 1)
149 try:
150 compress_func(data)
151 finally:
152 # Release memory
153 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000154
Antoine Pitrou89562712010-05-07 17:04:02 +0000155 def check_big_decompress_buffer(self, size, decompress_func):
156 data = b'x' * size
157 try:
158 compressed = zlib.compress(data, 1)
159 finally:
160 # Release memory
161 data = None
162 data = decompress_func(compressed)
163 # Sanity check
164 try:
165 self.assertEqual(len(data), size)
166 self.assertEqual(len(data.strip(b'x')), 0)
167 finally:
168 data = None
169
170
171class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000172 # Test compression in one go (whole message compression)
173 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000174 x = zlib.compress(HAMLET_SCENE)
175 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000176
Martin Panter1fe0d132016-02-10 10:06:36 +0000177 def test_keywords(self):
Serhiy Storchaka95657cd2016-06-25 22:43:05 +0300178 x = zlib.compress(HAMLET_SCENE, level=3)
Martin Panter1fe0d132016-02-10 10:06:36 +0000179 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Serhiy Storchaka95657cd2016-06-25 22:43:05 +0300180 with self.assertRaises(TypeError):
181 zlib.compress(data=HAMLET_SCENE, level=3)
Serhiy Storchaka15f32282016-08-15 10:06:16 +0300182 self.assertEqual(zlib.decompress(x,
183 wbits=zlib.MAX_WBITS,
184 bufsize=zlib.DEF_BUF_SIZE),
185 HAMLET_SCENE)
Martin Panter1fe0d132016-02-10 10:06:36 +0000186
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000187 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000188 # compress more data
189 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000190 x = zlib.compress(data)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000191 self.assertEqual(zlib.compress(bytearray(data)), x)
192 for ob in x, bytearray(x):
193 self.assertEqual(zlib.decompress(ob), data)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000194
Antoine Pitrou53b21662010-05-11 23:46:02 +0000195 def test_incomplete_stream(self):
Martin Panter6245cb32016-04-15 02:14:19 +0000196 # A useful error message is given
Antoine Pitrou53b21662010-05-11 23:46:02 +0000197 x = zlib.compress(HAMLET_SCENE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000198 self.assertRaisesRegex(zlib.error,
Antoine Pitrou53b21662010-05-11 23:46:02 +0000199 "Error -5 while decompressing data: incomplete or truncated stream",
200 zlib.decompress, x[:-1])
201
Antoine Pitrou89562712010-05-07 17:04:02 +0000202 # Memory use of the following functions takes into account overallocation
203
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200204 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000205 def test_big_compress_buffer(self, size):
206 compress = lambda s: zlib.compress(s, 1)
207 self.check_big_compress_buffer(size, compress)
208
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200209 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000210 def test_big_decompress_buffer(self, size):
211 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000212
Martin Pantere99e9772015-11-20 08:13:35 +0000213 @bigmemtest(size=_4G, memuse=1)
214 def test_large_bufsize(self, size):
215 # Test decompress(bufsize) parameter greater than the internal limit
216 data = HAMLET_SCENE * 10
217 compressed = zlib.compress(data, 1)
218 self.assertEqual(zlib.decompress(compressed, 15, size), data)
219
220 def test_custom_bufsize(self):
221 data = HAMLET_SCENE * 10
222 compressed = zlib.compress(data, 1)
223 self.assertEqual(zlib.decompress(compressed, 15, CustomInt()), data)
224
Martin Panter84544c12016-07-23 03:02:07 +0000225 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
226 @bigmemtest(size=_4G + 100, memuse=4)
227 def test_64bit_compress(self, size):
228 data = b'x' * size
229 try:
230 comp = zlib.compress(data, 0)
231 self.assertEqual(zlib.decompress(comp), data)
232 finally:
233 comp = data = None
234
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000235
Antoine Pitrou89562712010-05-07 17:04:02 +0000236class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000237 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000238 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000239 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000240 datasrc = HAMLET_SCENE * 128
241 datazip = zlib.compress(datasrc)
242 # should compress both bytes and bytearray data
243 for data in (datasrc, bytearray(datasrc)):
244 co = zlib.compressobj()
245 x1 = co.compress(data)
246 x2 = co.flush()
247 self.assertRaises(zlib.error, co.flush) # second flush should not work
248 self.assertEqual(x1 + x2, datazip)
249 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
250 dco = zlib.decompressobj()
251 y1 = dco.decompress(v1 + v2)
252 y2 = dco.flush()
253 self.assertEqual(data, y1 + y2)
254 self.assertIsInstance(dco.unconsumed_tail, bytes)
255 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000256
Serhiy Storchaka15f32282016-08-15 10:06:16 +0300257 def test_keywords(self):
258 level = 2
259 method = zlib.DEFLATED
260 wbits = -12
261 memLevel = 9
262 strategy = zlib.Z_FILTERED
263 co = zlib.compressobj(level=level,
264 method=method,
265 wbits=wbits,
266 memLevel=memLevel,
267 strategy=strategy,
268 zdict=b"")
269 do = zlib.decompressobj(wbits=wbits, zdict=b"")
270 with self.assertRaises(TypeError):
271 co.compress(data=HAMLET_SCENE)
272 with self.assertRaises(TypeError):
273 do.decompress(data=zlib.compress(HAMLET_SCENE))
274 x = co.compress(HAMLET_SCENE) + co.flush()
275 y = do.decompress(x, max_length=len(HAMLET_SCENE)) + do.flush()
276 self.assertEqual(HAMLET_SCENE, y)
277
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000278 def test_compressoptions(self):
279 # specify lots of options to compressobj()
280 level = 2
281 method = zlib.DEFLATED
282 wbits = -12
Martin Panterbf19d162015-09-09 01:01:13 +0000283 memLevel = 9
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000284 strategy = zlib.Z_FILTERED
Martin Panterbf19d162015-09-09 01:01:13 +0000285 co = zlib.compressobj(level, method, wbits, memLevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000286 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000287 x2 = co.flush()
288 dco = zlib.decompressobj(wbits)
289 y1 = dco.decompress(x1 + x2)
290 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000291 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000292
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000293 def test_compressincremental(self):
294 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000295 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000296 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000297 bufs = []
298 for i in range(0, len(data), 256):
299 bufs.append(co.compress(data[i:i+256]))
300 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000301 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000302
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000303 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000304 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000305 y2 = dco.flush()
306 self.assertEqual(data, y1 + y2)
307
Neil Schemenauer6412b122004-06-05 19:34:28 +0000308 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000309 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000310 source = source or HAMLET_SCENE
311 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000312 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000313 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000314 for i in range(0, len(data), cx):
315 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000316 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000317 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000318
Gregory P. Smith693fc462008-09-06 20:13:06 +0000319 decombuf = zlib.decompress(combuf)
320 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000321 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000322
323 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000324
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000325 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000326 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000327 for i in range(0, len(combuf), dcx):
328 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000329 self.assertEqual(b'', dco.unconsumed_tail, ########
330 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000331 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000332 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000333 if flush:
334 bufs.append(dco.flush())
335 else:
336 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000337 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000338 if chunk:
339 bufs.append(chunk)
340 else:
341 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000342 self.assertEqual(b'', dco.unconsumed_tail, ########
343 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000344 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000345 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000346 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000347 # Failure means: "decompressobj with init options failed"
348
Neil Schemenauer6412b122004-06-05 19:34:28 +0000349 def test_decompincflush(self):
350 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000351
Neil Schemenauer6412b122004-06-05 19:34:28 +0000352 def test_decompimax(self, source=None, cx=256, dcx=64):
353 # compress in steps, decompress in length-restricted steps
354 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000355 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000356 data = source * 128
357 co = zlib.compressobj()
358 bufs = []
359 for i in range(0, len(data), cx):
360 bufs.append(co.compress(data[i:i+cx]))
361 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000362 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000363 self.assertEqual(data, zlib.decompress(combuf),
364 'compressed data failure')
365
366 dco = zlib.decompressobj()
367 bufs = []
368 cb = combuf
369 while cb:
370 #max_length = 1 + len(cb)//10
371 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000372 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000373 'chunk too big (%d>%d)' % (len(chunk), dcx))
374 bufs.append(chunk)
375 cb = dco.unconsumed_tail
376 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000377 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000378
379 def test_decompressmaxlen(self, flush=False):
380 # Check a decompression object with max_length specified
381 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000382 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000383 bufs = []
384 for i in range(0, len(data), 256):
385 bufs.append(co.compress(data[i:i+256]))
386 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000387 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000388 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000389 'compressed data failure')
390
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000391 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000392 bufs = []
393 cb = combuf
394 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000395 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000396 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000397 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000398 'chunk too big (%d>%d)' % (len(chunk),max_length))
399 bufs.append(chunk)
400 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000401 if flush:
402 bufs.append(dco.flush())
403 else:
404 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000405 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000406 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000407 'chunk too big (%d>%d)' % (len(chunk),max_length))
408 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000409 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000410
Neil Schemenauer6412b122004-06-05 19:34:28 +0000411 def test_decompressmaxlenflush(self):
412 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000413
414 def test_maxlenmisc(self):
415 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000416 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000417 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000418 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000419
Martin Pantere99e9772015-11-20 08:13:35 +0000420 def test_maxlen_large(self):
421 # Sizes up to sys.maxsize should be accepted, although zlib is
422 # internally limited to expressing sizes with unsigned int
423 data = HAMLET_SCENE * 10
424 self.assertGreater(len(data), zlib.DEF_BUF_SIZE)
425 compressed = zlib.compress(data, 1)
426 dco = zlib.decompressobj()
427 self.assertEqual(dco.decompress(compressed, sys.maxsize), data)
428
429 def test_maxlen_custom(self):
430 data = HAMLET_SCENE * 10
431 compressed = zlib.compress(data, 1)
432 dco = zlib.decompressobj()
433 self.assertEqual(dco.decompress(compressed, CustomInt()), data[:100])
434
Nadeem Vawda7619e882011-05-14 14:05:20 +0200435 def test_clear_unconsumed_tail(self):
436 # Issue #12050: calling decompress() without providing max_length
437 # should clear the unconsumed_tail attribute.
438 cdata = b"x\x9cKLJ\x06\x00\x02M\x01" # "abc"
439 dco = zlib.decompressobj()
440 ddata = dco.decompress(cdata, 1)
441 ddata += dco.decompress(dco.unconsumed_tail)
442 self.assertEqual(dco.unconsumed_tail, b"")
443
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000444 def test_flushes(self):
445 # Test flush() with the various options, using all the
446 # different levels in order to provide more variations.
Xiang Zhangbc3f2282018-03-07 13:05:37 +0800447 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH',
Steve Dower57675092018-09-24 07:44:50 -0400448 'Z_PARTIAL_FLUSH']
449
450 ver = tuple(int(v) for v in zlib.ZLIB_RUNTIME_VERSION.split('.'))
451 # Z_BLOCK has a known failure prior to 1.2.5.3
452 if ver >= (1, 2, 5, 3):
453 sync_opt.append('Z_BLOCK')
454
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000455 sync_opt = [getattr(zlib, opt) for opt in sync_opt
456 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000457 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000458
459 for sync in sync_opt:
460 for level in range(10):
Steve Dower57675092018-09-24 07:44:50 -0400461 try:
462 obj = zlib.compressobj( level )
463 a = obj.compress( data[:3000] )
464 b = obj.flush( sync )
465 c = obj.compress( data[3000:] )
466 d = obj.flush()
467 except:
468 print("Error for flush mode={}, level={}"
469 .format(sync, level))
470 raise
Guido van Rossum776152b2007-05-22 22:44:07 +0000471 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000472 data, ("Decompress failed: flush "
473 "mode=%i, level=%i") % (sync, level))
474 del obj
475
Serhiy Storchaka43767632013-11-03 21:31:38 +0200476 @unittest.skipUnless(hasattr(zlib, 'Z_SYNC_FLUSH'),
477 'requires zlib.Z_SYNC_FLUSH')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000478 def test_odd_flush(self):
479 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
480 import random
Serhiy Storchaka43767632013-11-03 21:31:38 +0200481 # Testing on 17K of "random" data
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000482
Serhiy Storchaka43767632013-11-03 21:31:38 +0200483 # Create compressor and decompressor objects
484 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
485 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000486
Serhiy Storchaka43767632013-11-03 21:31:38 +0200487 # Try 17K of data
488 # generate random data stream
489 try:
490 # In 2.3 and later, WichmannHill is the RNG of the bug report
491 gen = random.WichmannHill()
492 except AttributeError:
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000493 try:
Serhiy Storchaka43767632013-11-03 21:31:38 +0200494 # 2.2 called it Random
495 gen = random.Random()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000496 except AttributeError:
Serhiy Storchaka43767632013-11-03 21:31:38 +0200497 # others might simply have a single RNG
498 gen = random
499 gen.seed(1)
Victor Stinner87502dd2020-04-17 22:54:38 +0200500 data = gen.randbytes(17 * 1024)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000501
Serhiy Storchaka43767632013-11-03 21:31:38 +0200502 # compress, sync-flush, and decompress
503 first = co.compress(data)
504 second = co.flush(zlib.Z_SYNC_FLUSH)
505 expanded = dco.decompress(first + second)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000506
Serhiy Storchaka43767632013-11-03 21:31:38 +0200507 # if decompressed data is different from the input data, choke.
508 self.assertEqual(expanded, data, "17K random source doesn't match")
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000509
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000510 def test_empty_flush(self):
511 # Test that calling .flush() on unused objects works.
512 # (Bug #1083110 -- calling .flush() on decompress objects
513 # caused a core dump.)
514
515 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000516 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000517 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000518 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000519
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200520 def test_dictionary(self):
521 h = HAMLET_SCENE
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200522 # Build a simulated dictionary out of the words in HAMLET.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200523 words = h.split()
524 random.shuffle(words)
525 zdict = b''.join(words)
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200526 # Use it to compress HAMLET.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200527 co = zlib.compressobj(zdict=zdict)
528 cd = co.compress(h) + co.flush()
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200529 # Verify that it will decompress with the dictionary.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200530 dco = zlib.decompressobj(zdict=zdict)
531 self.assertEqual(dco.decompress(cd) + dco.flush(), h)
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200532 # Verify that it fails when not given the dictionary.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200533 dco = zlib.decompressobj()
534 self.assertRaises(zlib.error, dco.decompress, cd)
535
536 def test_dictionary_streaming(self):
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200537 # This simulates the reuse of a compressor object for compressing
538 # several separate data streams.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200539 co = zlib.compressobj(zdict=HAMLET_SCENE)
540 do = zlib.decompressobj(zdict=HAMLET_SCENE)
541 piece = HAMLET_SCENE[1000:1500]
542 d0 = co.compress(piece) + co.flush(zlib.Z_SYNC_FLUSH)
543 d1 = co.compress(piece[100:]) + co.flush(zlib.Z_SYNC_FLUSH)
544 d2 = co.compress(piece[:-100]) + co.flush(zlib.Z_SYNC_FLUSH)
545 self.assertEqual(do.decompress(d0), piece)
546 self.assertEqual(do.decompress(d1), piece[100:])
547 self.assertEqual(do.decompress(d2), piece[:-100])
548
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000549 def test_decompress_incomplete_stream(self):
550 # This is 'foo', deflated
551 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
552 # For the record
553 self.assertEqual(zlib.decompress(x), b'foo')
554 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
555 # Omitting the stream end works with decompressor objects
556 # (see issue #8672).
557 dco = zlib.decompressobj()
558 y = dco.decompress(x[:-5])
559 y += dco.flush()
560 self.assertEqual(y, b'foo')
561
Nadeem Vawda1c385462011-08-13 15:22:40 +0200562 def test_decompress_eof(self):
563 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
564 dco = zlib.decompressobj()
565 self.assertFalse(dco.eof)
566 dco.decompress(x[:-5])
567 self.assertFalse(dco.eof)
568 dco.decompress(x[-5:])
569 self.assertTrue(dco.eof)
570 dco.flush()
571 self.assertTrue(dco.eof)
572
573 def test_decompress_eof_incomplete_stream(self):
574 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
575 dco = zlib.decompressobj()
576 self.assertFalse(dco.eof)
577 dco.decompress(x[:-5])
578 self.assertFalse(dco.eof)
579 dco.flush()
580 self.assertFalse(dco.eof)
581
Nadeem Vawda39079942012-11-05 00:37:42 +0100582 def test_decompress_unused_data(self):
583 # Repeated calls to decompress() after EOF should accumulate data in
584 # dco.unused_data, instead of just storing the arg to the last call.
Nadeem Vawdaee7889d2012-11-11 02:14:36 +0100585 source = b'abcdefghijklmnopqrstuvwxyz'
586 remainder = b'0123456789'
587 y = zlib.compress(source)
588 x = y + remainder
589 for maxlen in 0, 1000:
590 for step in 1, 2, len(y), len(x):
591 dco = zlib.decompressobj()
592 data = b''
593 for i in range(0, len(x), step):
594 if i < len(y):
595 self.assertEqual(dco.unused_data, b'')
596 if maxlen == 0:
597 data += dco.decompress(x[i : i + step])
598 self.assertEqual(dco.unconsumed_tail, b'')
599 else:
600 data += dco.decompress(
601 dco.unconsumed_tail + x[i : i + step], maxlen)
602 data += dco.flush()
Nadeem Vawdadd1253a2012-11-11 02:21:22 +0100603 self.assertTrue(dco.eof)
Nadeem Vawdaee7889d2012-11-11 02:14:36 +0100604 self.assertEqual(data, source)
605 self.assertEqual(dco.unconsumed_tail, b'')
606 self.assertEqual(dco.unused_data, remainder)
Nadeem Vawda39079942012-11-05 00:37:42 +0100607
Martin Panter3f0ee832016-06-05 10:48:34 +0000608 # issue27164
609 def test_decompress_raw_with_dictionary(self):
610 zdict = b'abcdefghijklmnopqrstuvwxyz'
611 co = zlib.compressobj(wbits=-zlib.MAX_WBITS, zdict=zdict)
612 comp = co.compress(zdict) + co.flush()
613 dco = zlib.decompressobj(wbits=-zlib.MAX_WBITS, zdict=zdict)
614 uncomp = dco.decompress(comp) + dco.flush()
615 self.assertEqual(zdict, uncomp)
616
Nadeem Vawda7ee95552012-11-11 03:15:32 +0100617 def test_flush_with_freed_input(self):
618 # Issue #16411: decompressor accesses input to last decompress() call
619 # in flush(), even if this object has been freed in the meanwhile.
620 input1 = b'abcdefghijklmnopqrstuvwxyz'
621 input2 = b'QWERTYUIOPASDFGHJKLZXCVBNM'
622 data = zlib.compress(input1)
623 dco = zlib.decompressobj()
624 dco.decompress(data, 1)
625 del data
626 data = zlib.compress(input2)
627 self.assertEqual(dco.flush(), input1[1:])
628
Martin Pantere99e9772015-11-20 08:13:35 +0000629 @bigmemtest(size=_4G, memuse=1)
630 def test_flush_large_length(self, size):
631 # Test flush(length) parameter greater than internal limit UINT_MAX
632 input = HAMLET_SCENE * 10
633 data = zlib.compress(input, 1)
634 dco = zlib.decompressobj()
635 dco.decompress(data, 1)
636 self.assertEqual(dco.flush(size), input[1:])
637
638 def test_flush_custom_length(self):
639 input = HAMLET_SCENE * 10
640 data = zlib.compress(input, 1)
641 dco = zlib.decompressobj()
642 dco.decompress(data, 1)
643 self.assertEqual(dco.flush(CustomInt()), input[1:])
644
Serhiy Storchaka43767632013-11-03 21:31:38 +0200645 @requires_Compress_copy
646 def test_compresscopy(self):
647 # Test copying a compression object
648 data0 = HAMLET_SCENE
649 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600650 for func in lambda c: c.copy(), copy.copy, copy.deepcopy:
651 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
652 bufs0 = []
653 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000654
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600655 c1 = func(c0)
656 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000657
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600658 bufs0.append(c0.compress(data0))
659 bufs0.append(c0.flush())
660 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000661
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600662 bufs1.append(c1.compress(data1))
663 bufs1.append(c1.flush())
664 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600666 self.assertEqual(zlib.decompress(s0),data0+data0)
667 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000668
Serhiy Storchaka43767632013-11-03 21:31:38 +0200669 @requires_Compress_copy
670 def test_badcompresscopy(self):
671 # Test copying a compression object in an inconsistent state
672 c = zlib.compressobj()
673 c.compress(HAMLET_SCENE)
674 c.flush()
675 self.assertRaises(ValueError, c.copy)
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600676 self.assertRaises(ValueError, copy.copy, c)
677 self.assertRaises(ValueError, copy.deepcopy, c)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000678
Serhiy Storchaka43767632013-11-03 21:31:38 +0200679 @requires_Decompress_copy
680 def test_decompresscopy(self):
681 # Test copying a decompression object
682 data = HAMLET_SCENE
683 comp = zlib.compress(data)
684 # Test type of return value
685 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000686
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600687 for func in lambda c: c.copy(), copy.copy, copy.deepcopy:
688 d0 = zlib.decompressobj()
689 bufs0 = []
690 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000691
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600692 d1 = func(d0)
693 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000694
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600695 bufs0.append(d0.decompress(comp[32:]))
696 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000697
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600698 bufs1.append(d1.decompress(comp[32:]))
699 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000700
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600701 self.assertEqual(s0,s1)
702 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000703
Serhiy Storchaka43767632013-11-03 21:31:38 +0200704 @requires_Decompress_copy
705 def test_baddecompresscopy(self):
706 # Test copying a compression object in an inconsistent state
707 data = zlib.compress(HAMLET_SCENE)
708 d = zlib.decompressobj()
709 d.decompress(data)
710 d.flush()
711 self.assertRaises(ValueError, d.copy)
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600712 self.assertRaises(ValueError, copy.copy, d)
713 self.assertRaises(ValueError, copy.deepcopy, d)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000714
Serhiy Storchakad7a44152015-11-12 11:23:04 +0200715 def test_compresspickle(self):
716 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
717 with self.assertRaises((TypeError, pickle.PicklingError)):
718 pickle.dumps(zlib.compressobj(zlib.Z_BEST_COMPRESSION), proto)
719
720 def test_decompresspickle(self):
721 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
722 with self.assertRaises((TypeError, pickle.PicklingError)):
723 pickle.dumps(zlib.decompressobj(), proto)
724
Antoine Pitrou89562712010-05-07 17:04:02 +0000725 # Memory use of the following functions takes into account overallocation
726
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200727 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000728 def test_big_compress_buffer(self, size):
729 c = zlib.compressobj(1)
730 compress = lambda s: c.compress(s) + c.flush()
731 self.check_big_compress_buffer(size, compress)
732
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200733 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000734 def test_big_decompress_buffer(self, size):
735 d = zlib.decompressobj()
736 decompress = lambda s: d.decompress(s) + d.flush()
737 self.check_big_decompress_buffer(size, decompress)
738
Martin Panter84544c12016-07-23 03:02:07 +0000739 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
740 @bigmemtest(size=_4G + 100, memuse=4)
741 def test_64bit_compress(self, size):
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200742 data = b'x' * size
Martin Panter84544c12016-07-23 03:02:07 +0000743 co = zlib.compressobj(0)
744 do = zlib.decompressobj()
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200745 try:
Martin Panter84544c12016-07-23 03:02:07 +0000746 comp = co.compress(data) + co.flush()
747 uncomp = do.decompress(comp) + do.flush()
748 self.assertEqual(uncomp, data)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200749 finally:
Martin Panter84544c12016-07-23 03:02:07 +0000750 comp = uncomp = data = None
751
752 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
753 @bigmemtest(size=_4G + 100, memuse=3)
754 def test_large_unused_data(self, size):
755 data = b'abcdefghijklmnop'
756 unused = b'x' * size
757 comp = zlib.compress(data) + unused
758 do = zlib.decompressobj()
759 try:
760 uncomp = do.decompress(comp) + do.flush()
761 self.assertEqual(unused, do.unused_data)
762 self.assertEqual(uncomp, data)
763 finally:
764 unused = comp = do = None
765
766 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
767 @bigmemtest(size=_4G + 100, memuse=5)
768 def test_large_unconsumed_tail(self, size):
769 data = b'x' * size
770 do = zlib.decompressobj()
771 try:
772 comp = zlib.compress(data, 0)
773 uncomp = do.decompress(comp, 1) + do.flush()
774 self.assertEqual(uncomp, data)
775 self.assertEqual(do.unconsumed_tail, b'')
776 finally:
777 comp = uncomp = data = None
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200778
Martin Panter0fdf41d2016-05-27 07:32:11 +0000779 def test_wbits(self):
Martin Panterc618ae82016-05-27 11:20:21 +0000780 # wbits=0 only supported since zlib v1.2.3.5
781 # Register "1.2.3" as "1.2.3.0"
pmp-p4c7108a2018-02-19 04:45:11 +0100782 # or "1.2.0-linux","1.2.0.f","1.2.0.f-linux"
783 v = zlib.ZLIB_RUNTIME_VERSION.split('-', 1)[0].split('.')
784 if len(v) < 4:
785 v.append('0')
786 elif not v[-1].isnumeric():
787 v[-1] = '0'
788
789 v = tuple(map(int, v))
790 supports_wbits_0 = v >= (1, 2, 3, 5)
Martin Panterc618ae82016-05-27 11:20:21 +0000791
Martin Panter0fdf41d2016-05-27 07:32:11 +0000792 co = zlib.compressobj(level=1, wbits=15)
793 zlib15 = co.compress(HAMLET_SCENE) + co.flush()
794 self.assertEqual(zlib.decompress(zlib15, 15), HAMLET_SCENE)
Martin Panterc618ae82016-05-27 11:20:21 +0000795 if supports_wbits_0:
796 self.assertEqual(zlib.decompress(zlib15, 0), HAMLET_SCENE)
Martin Panter0fdf41d2016-05-27 07:32:11 +0000797 self.assertEqual(zlib.decompress(zlib15, 32 + 15), HAMLET_SCENE)
798 with self.assertRaisesRegex(zlib.error, 'invalid window size'):
799 zlib.decompress(zlib15, 14)
800 dco = zlib.decompressobj(wbits=32 + 15)
801 self.assertEqual(dco.decompress(zlib15), HAMLET_SCENE)
802 dco = zlib.decompressobj(wbits=14)
803 with self.assertRaisesRegex(zlib.error, 'invalid window size'):
804 dco.decompress(zlib15)
805
806 co = zlib.compressobj(level=1, wbits=9)
807 zlib9 = co.compress(HAMLET_SCENE) + co.flush()
808 self.assertEqual(zlib.decompress(zlib9, 9), HAMLET_SCENE)
809 self.assertEqual(zlib.decompress(zlib9, 15), HAMLET_SCENE)
Martin Panterc618ae82016-05-27 11:20:21 +0000810 if supports_wbits_0:
811 self.assertEqual(zlib.decompress(zlib9, 0), HAMLET_SCENE)
Martin Panter0fdf41d2016-05-27 07:32:11 +0000812 self.assertEqual(zlib.decompress(zlib9, 32 + 9), HAMLET_SCENE)
813 dco = zlib.decompressobj(wbits=32 + 9)
814 self.assertEqual(dco.decompress(zlib9), HAMLET_SCENE)
815
816 co = zlib.compressobj(level=1, wbits=-15)
817 deflate15 = co.compress(HAMLET_SCENE) + co.flush()
818 self.assertEqual(zlib.decompress(deflate15, -15), HAMLET_SCENE)
819 dco = zlib.decompressobj(wbits=-15)
820 self.assertEqual(dco.decompress(deflate15), HAMLET_SCENE)
821
822 co = zlib.compressobj(level=1, wbits=-9)
823 deflate9 = co.compress(HAMLET_SCENE) + co.flush()
824 self.assertEqual(zlib.decompress(deflate9, -9), HAMLET_SCENE)
825 self.assertEqual(zlib.decompress(deflate9, -15), HAMLET_SCENE)
826 dco = zlib.decompressobj(wbits=-9)
827 self.assertEqual(dco.decompress(deflate9), HAMLET_SCENE)
828
829 co = zlib.compressobj(level=1, wbits=16 + 15)
830 gzip = co.compress(HAMLET_SCENE) + co.flush()
831 self.assertEqual(zlib.decompress(gzip, 16 + 15), HAMLET_SCENE)
832 self.assertEqual(zlib.decompress(gzip, 32 + 15), HAMLET_SCENE)
833 dco = zlib.decompressobj(32 + 15)
834 self.assertEqual(dco.decompress(gzip), HAMLET_SCENE)
835
Antoine Pitrou89562712010-05-07 17:04:02 +0000836
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000837def choose_lines(source, number, seed=None, generator=random):
838 """Return a list of number lines randomly chosen from the source"""
839 if seed is not None:
840 generator.seed(seed)
841 sources = source.split('\n')
842 return [generator.choice(sources) for n in range(number)]
843
844
Guido van Rossum776152b2007-05-22 22:44:07 +0000845HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000846LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000847
848 O, fear me not.
849 I stay too long: but here my father comes.
850
851 Enter POLONIUS
852
853 A double blessing is a double grace,
854 Occasion smiles upon a second leave.
855
Fred Drake004d5e62000-10-23 17:22:08 +0000856LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000857
858 Yet here, Laertes! aboard, aboard, for shame!
859 The wind sits in the shoulder of your sail,
860 And you are stay'd for. There; my blessing with thee!
861 And these few precepts in thy memory
862 See thou character. Give thy thoughts no tongue,
863 Nor any unproportioned thought his act.
864 Be thou familiar, but by no means vulgar.
865 Those friends thou hast, and their adoption tried,
866 Grapple them to thy soul with hoops of steel;
867 But do not dull thy palm with entertainment
868 Of each new-hatch'd, unfledged comrade. Beware
869 Of entrance to a quarrel, but being in,
870 Bear't that the opposed may beware of thee.
871 Give every man thy ear, but few thy voice;
872 Take each man's censure, but reserve thy judgment.
873 Costly thy habit as thy purse can buy,
874 But not express'd in fancy; rich, not gaudy;
875 For the apparel oft proclaims the man,
876 And they in France of the best rank and station
877 Are of a most select and generous chief in that.
878 Neither a borrower nor a lender be;
879 For loan oft loses both itself and friend,
880 And borrowing dulls the edge of husbandry.
881 This above all: to thine ownself be true,
882 And it must follow, as the night the day,
883 Thou canst not then be false to any man.
884 Farewell: my blessing season this in thee!
885
Fred Drake004d5e62000-10-23 17:22:08 +0000886LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000887
888 Most humbly do I take my leave, my lord.
889
Fred Drake004d5e62000-10-23 17:22:08 +0000890LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000891
892 The time invites you; go; your servants tend.
893
Fred Drake004d5e62000-10-23 17:22:08 +0000894LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000895
896 Farewell, Ophelia; and remember well
897 What I have said to you.
898
Fred Drake004d5e62000-10-23 17:22:08 +0000899OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000900
901 'Tis in my memory lock'd,
902 And you yourself shall keep the key of it.
903
Fred Drake004d5e62000-10-23 17:22:08 +0000904LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000905
906 Farewell.
907"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000908
909
Martin Pantere99e9772015-11-20 08:13:35 +0000910class CustomInt:
Serhiy Storchaka6a44f6e2019-02-25 17:57:58 +0200911 def __index__(self):
Martin Pantere99e9772015-11-20 08:13:35 +0000912 return 100
913
914
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000915if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500916 unittest.main()