blob: 7f30cac64f71b93caceffd536706929372da728e [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
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000132
Antoine Pitrou89562712010-05-07 17:04:02 +0000133class BaseCompressTestCase(object):
134 def check_big_compress_buffer(self, size, compress_func):
135 _1M = 1024 * 1024
Victor Stinner8c663fd2017-11-08 14:44:44 -0800136 # Generate 10 MiB worth of random, and expand it by repeating it.
Antoine Pitrou89562712010-05-07 17:04:02 +0000137 # The assumption is that zlib's memory is not big enough to exploit
138 # such spread out redundancy.
Victor Stinner87502dd2020-04-17 22:54:38 +0200139 data = random.randbytes(_1M * 10)
Antoine Pitrou89562712010-05-07 17:04:02 +0000140 data = data * (size // len(data) + 1)
141 try:
142 compress_func(data)
143 finally:
144 # Release memory
145 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000146
Antoine Pitrou89562712010-05-07 17:04:02 +0000147 def check_big_decompress_buffer(self, size, decompress_func):
148 data = b'x' * size
149 try:
150 compressed = zlib.compress(data, 1)
151 finally:
152 # Release memory
153 data = None
154 data = decompress_func(compressed)
155 # Sanity check
156 try:
157 self.assertEqual(len(data), size)
158 self.assertEqual(len(data.strip(b'x')), 0)
159 finally:
160 data = None
161
162
163class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000164 # Test compression in one go (whole message compression)
165 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000166 x = zlib.compress(HAMLET_SCENE)
167 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000168
Martin Panter1fe0d132016-02-10 10:06:36 +0000169 def test_keywords(self):
Serhiy Storchaka95657cd2016-06-25 22:43:05 +0300170 x = zlib.compress(HAMLET_SCENE, level=3)
Martin Panter1fe0d132016-02-10 10:06:36 +0000171 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Serhiy Storchaka95657cd2016-06-25 22:43:05 +0300172 with self.assertRaises(TypeError):
173 zlib.compress(data=HAMLET_SCENE, level=3)
Serhiy Storchaka15f32282016-08-15 10:06:16 +0300174 self.assertEqual(zlib.decompress(x,
175 wbits=zlib.MAX_WBITS,
176 bufsize=zlib.DEF_BUF_SIZE),
177 HAMLET_SCENE)
Martin Panter1fe0d132016-02-10 10:06:36 +0000178
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000179 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000180 # compress more data
181 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000182 x = zlib.compress(data)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000183 self.assertEqual(zlib.compress(bytearray(data)), x)
184 for ob in x, bytearray(x):
185 self.assertEqual(zlib.decompress(ob), data)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000186
Antoine Pitrou53b21662010-05-11 23:46:02 +0000187 def test_incomplete_stream(self):
Martin Panter6245cb32016-04-15 02:14:19 +0000188 # A useful error message is given
Antoine Pitrou53b21662010-05-11 23:46:02 +0000189 x = zlib.compress(HAMLET_SCENE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000190 self.assertRaisesRegex(zlib.error,
Antoine Pitrou53b21662010-05-11 23:46:02 +0000191 "Error -5 while decompressing data: incomplete or truncated stream",
192 zlib.decompress, x[:-1])
193
Antoine Pitrou89562712010-05-07 17:04:02 +0000194 # Memory use of the following functions takes into account overallocation
195
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200196 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000197 def test_big_compress_buffer(self, size):
198 compress = lambda s: zlib.compress(s, 1)
199 self.check_big_compress_buffer(size, compress)
200
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200201 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000202 def test_big_decompress_buffer(self, size):
203 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000204
Martin Pantere99e9772015-11-20 08:13:35 +0000205 @bigmemtest(size=_4G, memuse=1)
206 def test_large_bufsize(self, size):
207 # Test decompress(bufsize) parameter greater than the internal limit
208 data = HAMLET_SCENE * 10
209 compressed = zlib.compress(data, 1)
210 self.assertEqual(zlib.decompress(compressed, 15, size), data)
211
212 def test_custom_bufsize(self):
213 data = HAMLET_SCENE * 10
214 compressed = zlib.compress(data, 1)
215 self.assertEqual(zlib.decompress(compressed, 15, CustomInt()), data)
216
Martin Panter84544c12016-07-23 03:02:07 +0000217 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
218 @bigmemtest(size=_4G + 100, memuse=4)
219 def test_64bit_compress(self, size):
220 data = b'x' * size
221 try:
222 comp = zlib.compress(data, 0)
223 self.assertEqual(zlib.decompress(comp), data)
224 finally:
225 comp = data = None
226
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000227
Antoine Pitrou89562712010-05-07 17:04:02 +0000228class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000229 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000230 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000231 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000232 datasrc = HAMLET_SCENE * 128
233 datazip = zlib.compress(datasrc)
234 # should compress both bytes and bytearray data
235 for data in (datasrc, bytearray(datasrc)):
236 co = zlib.compressobj()
237 x1 = co.compress(data)
238 x2 = co.flush()
239 self.assertRaises(zlib.error, co.flush) # second flush should not work
240 self.assertEqual(x1 + x2, datazip)
241 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
242 dco = zlib.decompressobj()
243 y1 = dco.decompress(v1 + v2)
244 y2 = dco.flush()
245 self.assertEqual(data, y1 + y2)
246 self.assertIsInstance(dco.unconsumed_tail, bytes)
247 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000248
Serhiy Storchaka15f32282016-08-15 10:06:16 +0300249 def test_keywords(self):
250 level = 2
251 method = zlib.DEFLATED
252 wbits = -12
253 memLevel = 9
254 strategy = zlib.Z_FILTERED
255 co = zlib.compressobj(level=level,
256 method=method,
257 wbits=wbits,
258 memLevel=memLevel,
259 strategy=strategy,
260 zdict=b"")
261 do = zlib.decompressobj(wbits=wbits, zdict=b"")
262 with self.assertRaises(TypeError):
263 co.compress(data=HAMLET_SCENE)
264 with self.assertRaises(TypeError):
265 do.decompress(data=zlib.compress(HAMLET_SCENE))
266 x = co.compress(HAMLET_SCENE) + co.flush()
267 y = do.decompress(x, max_length=len(HAMLET_SCENE)) + do.flush()
268 self.assertEqual(HAMLET_SCENE, y)
269
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000270 def test_compressoptions(self):
271 # specify lots of options to compressobj()
272 level = 2
273 method = zlib.DEFLATED
274 wbits = -12
Martin Panterbf19d162015-09-09 01:01:13 +0000275 memLevel = 9
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000276 strategy = zlib.Z_FILTERED
Martin Panterbf19d162015-09-09 01:01:13 +0000277 co = zlib.compressobj(level, method, wbits, memLevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000278 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000279 x2 = co.flush()
280 dco = zlib.decompressobj(wbits)
281 y1 = dco.decompress(x1 + x2)
282 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000283 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000284
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000285 def test_compressincremental(self):
286 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000287 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000288 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000289 bufs = []
290 for i in range(0, len(data), 256):
291 bufs.append(co.compress(data[i:i+256]))
292 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000293 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000294
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000295 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000296 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000297 y2 = dco.flush()
298 self.assertEqual(data, y1 + y2)
299
Neil Schemenauer6412b122004-06-05 19:34:28 +0000300 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000301 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000302 source = source or HAMLET_SCENE
303 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000304 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000305 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000306 for i in range(0, len(data), cx):
307 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000308 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000309 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000310
Gregory P. Smith693fc462008-09-06 20:13:06 +0000311 decombuf = zlib.decompress(combuf)
312 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000313 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000314
315 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000316
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000317 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000318 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000319 for i in range(0, len(combuf), dcx):
320 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000321 self.assertEqual(b'', dco.unconsumed_tail, ########
322 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000323 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000324 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000325 if flush:
326 bufs.append(dco.flush())
327 else:
328 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000329 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000330 if chunk:
331 bufs.append(chunk)
332 else:
333 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000334 self.assertEqual(b'', dco.unconsumed_tail, ########
335 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000336 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000337 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000338 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000339 # Failure means: "decompressobj with init options failed"
340
Neil Schemenauer6412b122004-06-05 19:34:28 +0000341 def test_decompincflush(self):
342 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000343
Neil Schemenauer6412b122004-06-05 19:34:28 +0000344 def test_decompimax(self, source=None, cx=256, dcx=64):
345 # compress in steps, decompress in length-restricted steps
346 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000347 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000348 data = source * 128
349 co = zlib.compressobj()
350 bufs = []
351 for i in range(0, len(data), cx):
352 bufs.append(co.compress(data[i:i+cx]))
353 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000354 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000355 self.assertEqual(data, zlib.decompress(combuf),
356 'compressed data failure')
357
358 dco = zlib.decompressobj()
359 bufs = []
360 cb = combuf
361 while cb:
362 #max_length = 1 + len(cb)//10
363 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000364 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000365 'chunk too big (%d>%d)' % (len(chunk), dcx))
366 bufs.append(chunk)
367 cb = dco.unconsumed_tail
368 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000369 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000370
371 def test_decompressmaxlen(self, flush=False):
372 # Check a decompression object with max_length specified
373 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000374 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000375 bufs = []
376 for i in range(0, len(data), 256):
377 bufs.append(co.compress(data[i:i+256]))
378 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000379 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000380 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000381 'compressed data failure')
382
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000383 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000384 bufs = []
385 cb = combuf
386 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000387 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000388 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000389 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000390 'chunk too big (%d>%d)' % (len(chunk),max_length))
391 bufs.append(chunk)
392 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000393 if flush:
394 bufs.append(dco.flush())
395 else:
396 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000397 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000398 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000399 'chunk too big (%d>%d)' % (len(chunk),max_length))
400 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000401 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000402
Neil Schemenauer6412b122004-06-05 19:34:28 +0000403 def test_decompressmaxlenflush(self):
404 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000405
406 def test_maxlenmisc(self):
407 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000408 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000409 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000410 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000411
Martin Pantere99e9772015-11-20 08:13:35 +0000412 def test_maxlen_large(self):
413 # Sizes up to sys.maxsize should be accepted, although zlib is
414 # internally limited to expressing sizes with unsigned int
415 data = HAMLET_SCENE * 10
416 self.assertGreater(len(data), zlib.DEF_BUF_SIZE)
417 compressed = zlib.compress(data, 1)
418 dco = zlib.decompressobj()
419 self.assertEqual(dco.decompress(compressed, sys.maxsize), data)
420
421 def test_maxlen_custom(self):
422 data = HAMLET_SCENE * 10
423 compressed = zlib.compress(data, 1)
424 dco = zlib.decompressobj()
425 self.assertEqual(dco.decompress(compressed, CustomInt()), data[:100])
426
Nadeem Vawda7619e882011-05-14 14:05:20 +0200427 def test_clear_unconsumed_tail(self):
428 # Issue #12050: calling decompress() without providing max_length
429 # should clear the unconsumed_tail attribute.
430 cdata = b"x\x9cKLJ\x06\x00\x02M\x01" # "abc"
431 dco = zlib.decompressobj()
432 ddata = dco.decompress(cdata, 1)
433 ddata += dco.decompress(dco.unconsumed_tail)
434 self.assertEqual(dco.unconsumed_tail, b"")
435
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000436 def test_flushes(self):
437 # Test flush() with the various options, using all the
438 # different levels in order to provide more variations.
Xiang Zhangbc3f2282018-03-07 13:05:37 +0800439 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH',
Steve Dower57675092018-09-24 07:44:50 -0400440 'Z_PARTIAL_FLUSH']
441
442 ver = tuple(int(v) for v in zlib.ZLIB_RUNTIME_VERSION.split('.'))
443 # Z_BLOCK has a known failure prior to 1.2.5.3
444 if ver >= (1, 2, 5, 3):
445 sync_opt.append('Z_BLOCK')
446
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000447 sync_opt = [getattr(zlib, opt) for opt in sync_opt
448 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000449 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000450
451 for sync in sync_opt:
452 for level in range(10):
Steve Dower57675092018-09-24 07:44:50 -0400453 try:
454 obj = zlib.compressobj( level )
455 a = obj.compress( data[:3000] )
456 b = obj.flush( sync )
457 c = obj.compress( data[3000:] )
458 d = obj.flush()
459 except:
460 print("Error for flush mode={}, level={}"
461 .format(sync, level))
462 raise
Guido van Rossum776152b2007-05-22 22:44:07 +0000463 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000464 data, ("Decompress failed: flush "
465 "mode=%i, level=%i") % (sync, level))
466 del obj
467
Serhiy Storchaka43767632013-11-03 21:31:38 +0200468 @unittest.skipUnless(hasattr(zlib, 'Z_SYNC_FLUSH'),
469 'requires zlib.Z_SYNC_FLUSH')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000470 def test_odd_flush(self):
471 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
472 import random
Serhiy Storchaka43767632013-11-03 21:31:38 +0200473 # Testing on 17K of "random" data
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000474
Serhiy Storchaka43767632013-11-03 21:31:38 +0200475 # Create compressor and decompressor objects
476 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
477 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000478
Serhiy Storchaka43767632013-11-03 21:31:38 +0200479 # Try 17K of data
480 # generate random data stream
481 try:
482 # In 2.3 and later, WichmannHill is the RNG of the bug report
483 gen = random.WichmannHill()
484 except AttributeError:
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000485 try:
Serhiy Storchaka43767632013-11-03 21:31:38 +0200486 # 2.2 called it Random
487 gen = random.Random()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000488 except AttributeError:
Serhiy Storchaka43767632013-11-03 21:31:38 +0200489 # others might simply have a single RNG
490 gen = random
491 gen.seed(1)
Victor Stinner87502dd2020-04-17 22:54:38 +0200492 data = gen.randbytes(17 * 1024)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000493
Serhiy Storchaka43767632013-11-03 21:31:38 +0200494 # compress, sync-flush, and decompress
495 first = co.compress(data)
496 second = co.flush(zlib.Z_SYNC_FLUSH)
497 expanded = dco.decompress(first + second)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000498
Serhiy Storchaka43767632013-11-03 21:31:38 +0200499 # if decompressed data is different from the input data, choke.
500 self.assertEqual(expanded, data, "17K random source doesn't match")
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000501
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000502 def test_empty_flush(self):
503 # Test that calling .flush() on unused objects works.
504 # (Bug #1083110 -- calling .flush() on decompress objects
505 # caused a core dump.)
506
507 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000508 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000509 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000510 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000511
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200512 def test_dictionary(self):
513 h = HAMLET_SCENE
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200514 # Build a simulated dictionary out of the words in HAMLET.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200515 words = h.split()
516 random.shuffle(words)
517 zdict = b''.join(words)
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200518 # Use it to compress HAMLET.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200519 co = zlib.compressobj(zdict=zdict)
520 cd = co.compress(h) + co.flush()
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200521 # Verify that it will decompress with the dictionary.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200522 dco = zlib.decompressobj(zdict=zdict)
523 self.assertEqual(dco.decompress(cd) + dco.flush(), h)
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200524 # Verify that it fails when not given the dictionary.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200525 dco = zlib.decompressobj()
526 self.assertRaises(zlib.error, dco.decompress, cd)
527
528 def test_dictionary_streaming(self):
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200529 # This simulates the reuse of a compressor object for compressing
530 # several separate data streams.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200531 co = zlib.compressobj(zdict=HAMLET_SCENE)
532 do = zlib.decompressobj(zdict=HAMLET_SCENE)
533 piece = HAMLET_SCENE[1000:1500]
534 d0 = co.compress(piece) + co.flush(zlib.Z_SYNC_FLUSH)
535 d1 = co.compress(piece[100:]) + co.flush(zlib.Z_SYNC_FLUSH)
536 d2 = co.compress(piece[:-100]) + co.flush(zlib.Z_SYNC_FLUSH)
537 self.assertEqual(do.decompress(d0), piece)
538 self.assertEqual(do.decompress(d1), piece[100:])
539 self.assertEqual(do.decompress(d2), piece[:-100])
540
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000541 def test_decompress_incomplete_stream(self):
542 # This is 'foo', deflated
543 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
544 # For the record
545 self.assertEqual(zlib.decompress(x), b'foo')
546 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
547 # Omitting the stream end works with decompressor objects
548 # (see issue #8672).
549 dco = zlib.decompressobj()
550 y = dco.decompress(x[:-5])
551 y += dco.flush()
552 self.assertEqual(y, b'foo')
553
Nadeem Vawda1c385462011-08-13 15:22:40 +0200554 def test_decompress_eof(self):
555 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
556 dco = zlib.decompressobj()
557 self.assertFalse(dco.eof)
558 dco.decompress(x[:-5])
559 self.assertFalse(dco.eof)
560 dco.decompress(x[-5:])
561 self.assertTrue(dco.eof)
562 dco.flush()
563 self.assertTrue(dco.eof)
564
565 def test_decompress_eof_incomplete_stream(self):
566 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
567 dco = zlib.decompressobj()
568 self.assertFalse(dco.eof)
569 dco.decompress(x[:-5])
570 self.assertFalse(dco.eof)
571 dco.flush()
572 self.assertFalse(dco.eof)
573
Nadeem Vawda39079942012-11-05 00:37:42 +0100574 def test_decompress_unused_data(self):
575 # Repeated calls to decompress() after EOF should accumulate data in
576 # dco.unused_data, instead of just storing the arg to the last call.
Nadeem Vawdaee7889d2012-11-11 02:14:36 +0100577 source = b'abcdefghijklmnopqrstuvwxyz'
578 remainder = b'0123456789'
579 y = zlib.compress(source)
580 x = y + remainder
581 for maxlen in 0, 1000:
582 for step in 1, 2, len(y), len(x):
583 dco = zlib.decompressobj()
584 data = b''
585 for i in range(0, len(x), step):
586 if i < len(y):
587 self.assertEqual(dco.unused_data, b'')
588 if maxlen == 0:
589 data += dco.decompress(x[i : i + step])
590 self.assertEqual(dco.unconsumed_tail, b'')
591 else:
592 data += dco.decompress(
593 dco.unconsumed_tail + x[i : i + step], maxlen)
594 data += dco.flush()
Nadeem Vawdadd1253a2012-11-11 02:21:22 +0100595 self.assertTrue(dco.eof)
Nadeem Vawdaee7889d2012-11-11 02:14:36 +0100596 self.assertEqual(data, source)
597 self.assertEqual(dco.unconsumed_tail, b'')
598 self.assertEqual(dco.unused_data, remainder)
Nadeem Vawda39079942012-11-05 00:37:42 +0100599
Martin Panter3f0ee832016-06-05 10:48:34 +0000600 # issue27164
601 def test_decompress_raw_with_dictionary(self):
602 zdict = b'abcdefghijklmnopqrstuvwxyz'
603 co = zlib.compressobj(wbits=-zlib.MAX_WBITS, zdict=zdict)
604 comp = co.compress(zdict) + co.flush()
605 dco = zlib.decompressobj(wbits=-zlib.MAX_WBITS, zdict=zdict)
606 uncomp = dco.decompress(comp) + dco.flush()
607 self.assertEqual(zdict, uncomp)
608
Nadeem Vawda7ee95552012-11-11 03:15:32 +0100609 def test_flush_with_freed_input(self):
610 # Issue #16411: decompressor accesses input to last decompress() call
611 # in flush(), even if this object has been freed in the meanwhile.
612 input1 = b'abcdefghijklmnopqrstuvwxyz'
613 input2 = b'QWERTYUIOPASDFGHJKLZXCVBNM'
614 data = zlib.compress(input1)
615 dco = zlib.decompressobj()
616 dco.decompress(data, 1)
617 del data
618 data = zlib.compress(input2)
619 self.assertEqual(dco.flush(), input1[1:])
620
Martin Pantere99e9772015-11-20 08:13:35 +0000621 @bigmemtest(size=_4G, memuse=1)
622 def test_flush_large_length(self, size):
623 # Test flush(length) parameter greater than internal limit UINT_MAX
624 input = HAMLET_SCENE * 10
625 data = zlib.compress(input, 1)
626 dco = zlib.decompressobj()
627 dco.decompress(data, 1)
628 self.assertEqual(dco.flush(size), input[1:])
629
630 def test_flush_custom_length(self):
631 input = HAMLET_SCENE * 10
632 data = zlib.compress(input, 1)
633 dco = zlib.decompressobj()
634 dco.decompress(data, 1)
635 self.assertEqual(dco.flush(CustomInt()), input[1:])
636
Serhiy Storchaka43767632013-11-03 21:31:38 +0200637 @requires_Compress_copy
638 def test_compresscopy(self):
639 # Test copying a compression object
640 data0 = HAMLET_SCENE
641 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600642 for func in lambda c: c.copy(), copy.copy, copy.deepcopy:
643 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
644 bufs0 = []
645 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000646
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600647 c1 = func(c0)
648 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000649
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600650 bufs0.append(c0.compress(data0))
651 bufs0.append(c0.flush())
652 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000653
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600654 bufs1.append(c1.compress(data1))
655 bufs1.append(c1.flush())
656 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000657
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600658 self.assertEqual(zlib.decompress(s0),data0+data0)
659 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000660
Serhiy Storchaka43767632013-11-03 21:31:38 +0200661 @requires_Compress_copy
662 def test_badcompresscopy(self):
663 # Test copying a compression object in an inconsistent state
664 c = zlib.compressobj()
665 c.compress(HAMLET_SCENE)
666 c.flush()
667 self.assertRaises(ValueError, c.copy)
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600668 self.assertRaises(ValueError, copy.copy, c)
669 self.assertRaises(ValueError, copy.deepcopy, c)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000670
Serhiy Storchaka43767632013-11-03 21:31:38 +0200671 @requires_Decompress_copy
672 def test_decompresscopy(self):
673 # Test copying a decompression object
674 data = HAMLET_SCENE
675 comp = zlib.compress(data)
676 # Test type of return value
677 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000678
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600679 for func in lambda c: c.copy(), copy.copy, copy.deepcopy:
680 d0 = zlib.decompressobj()
681 bufs0 = []
682 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000683
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600684 d1 = func(d0)
685 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000686
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600687 bufs0.append(d0.decompress(comp[32:]))
688 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000689
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600690 bufs1.append(d1.decompress(comp[32:]))
691 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000692
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600693 self.assertEqual(s0,s1)
694 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000695
Serhiy Storchaka43767632013-11-03 21:31:38 +0200696 @requires_Decompress_copy
697 def test_baddecompresscopy(self):
698 # Test copying a compression object in an inconsistent state
699 data = zlib.compress(HAMLET_SCENE)
700 d = zlib.decompressobj()
701 d.decompress(data)
702 d.flush()
703 self.assertRaises(ValueError, d.copy)
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600704 self.assertRaises(ValueError, copy.copy, d)
705 self.assertRaises(ValueError, copy.deepcopy, d)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000706
Serhiy Storchakad7a44152015-11-12 11:23:04 +0200707 def test_compresspickle(self):
708 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
709 with self.assertRaises((TypeError, pickle.PicklingError)):
710 pickle.dumps(zlib.compressobj(zlib.Z_BEST_COMPRESSION), proto)
711
712 def test_decompresspickle(self):
713 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
714 with self.assertRaises((TypeError, pickle.PicklingError)):
715 pickle.dumps(zlib.decompressobj(), proto)
716
Antoine Pitrou89562712010-05-07 17:04:02 +0000717 # Memory use of the following functions takes into account overallocation
718
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200719 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000720 def test_big_compress_buffer(self, size):
721 c = zlib.compressobj(1)
722 compress = lambda s: c.compress(s) + c.flush()
723 self.check_big_compress_buffer(size, compress)
724
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200725 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000726 def test_big_decompress_buffer(self, size):
727 d = zlib.decompressobj()
728 decompress = lambda s: d.decompress(s) + d.flush()
729 self.check_big_decompress_buffer(size, decompress)
730
Martin Panter84544c12016-07-23 03:02:07 +0000731 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
732 @bigmemtest(size=_4G + 100, memuse=4)
733 def test_64bit_compress(self, size):
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200734 data = b'x' * size
Martin Panter84544c12016-07-23 03:02:07 +0000735 co = zlib.compressobj(0)
736 do = zlib.decompressobj()
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200737 try:
Martin Panter84544c12016-07-23 03:02:07 +0000738 comp = co.compress(data) + co.flush()
739 uncomp = do.decompress(comp) + do.flush()
740 self.assertEqual(uncomp, data)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200741 finally:
Martin Panter84544c12016-07-23 03:02:07 +0000742 comp = uncomp = data = None
743
744 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
745 @bigmemtest(size=_4G + 100, memuse=3)
746 def test_large_unused_data(self, size):
747 data = b'abcdefghijklmnop'
748 unused = b'x' * size
749 comp = zlib.compress(data) + unused
750 do = zlib.decompressobj()
751 try:
752 uncomp = do.decompress(comp) + do.flush()
753 self.assertEqual(unused, do.unused_data)
754 self.assertEqual(uncomp, data)
755 finally:
756 unused = comp = do = None
757
758 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
759 @bigmemtest(size=_4G + 100, memuse=5)
760 def test_large_unconsumed_tail(self, size):
761 data = b'x' * size
762 do = zlib.decompressobj()
763 try:
764 comp = zlib.compress(data, 0)
765 uncomp = do.decompress(comp, 1) + do.flush()
766 self.assertEqual(uncomp, data)
767 self.assertEqual(do.unconsumed_tail, b'')
768 finally:
769 comp = uncomp = data = None
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200770
Martin Panter0fdf41d2016-05-27 07:32:11 +0000771 def test_wbits(self):
Martin Panterc618ae82016-05-27 11:20:21 +0000772 # wbits=0 only supported since zlib v1.2.3.5
773 # Register "1.2.3" as "1.2.3.0"
pmp-p4c7108a2018-02-19 04:45:11 +0100774 # or "1.2.0-linux","1.2.0.f","1.2.0.f-linux"
775 v = zlib.ZLIB_RUNTIME_VERSION.split('-', 1)[0].split('.')
776 if len(v) < 4:
777 v.append('0')
778 elif not v[-1].isnumeric():
779 v[-1] = '0'
780
781 v = tuple(map(int, v))
782 supports_wbits_0 = v >= (1, 2, 3, 5)
Martin Panterc618ae82016-05-27 11:20:21 +0000783
Martin Panter0fdf41d2016-05-27 07:32:11 +0000784 co = zlib.compressobj(level=1, wbits=15)
785 zlib15 = co.compress(HAMLET_SCENE) + co.flush()
786 self.assertEqual(zlib.decompress(zlib15, 15), HAMLET_SCENE)
Martin Panterc618ae82016-05-27 11:20:21 +0000787 if supports_wbits_0:
788 self.assertEqual(zlib.decompress(zlib15, 0), HAMLET_SCENE)
Martin Panter0fdf41d2016-05-27 07:32:11 +0000789 self.assertEqual(zlib.decompress(zlib15, 32 + 15), HAMLET_SCENE)
790 with self.assertRaisesRegex(zlib.error, 'invalid window size'):
791 zlib.decompress(zlib15, 14)
792 dco = zlib.decompressobj(wbits=32 + 15)
793 self.assertEqual(dco.decompress(zlib15), HAMLET_SCENE)
794 dco = zlib.decompressobj(wbits=14)
795 with self.assertRaisesRegex(zlib.error, 'invalid window size'):
796 dco.decompress(zlib15)
797
798 co = zlib.compressobj(level=1, wbits=9)
799 zlib9 = co.compress(HAMLET_SCENE) + co.flush()
800 self.assertEqual(zlib.decompress(zlib9, 9), HAMLET_SCENE)
801 self.assertEqual(zlib.decompress(zlib9, 15), HAMLET_SCENE)
Martin Panterc618ae82016-05-27 11:20:21 +0000802 if supports_wbits_0:
803 self.assertEqual(zlib.decompress(zlib9, 0), HAMLET_SCENE)
Martin Panter0fdf41d2016-05-27 07:32:11 +0000804 self.assertEqual(zlib.decompress(zlib9, 32 + 9), HAMLET_SCENE)
805 dco = zlib.decompressobj(wbits=32 + 9)
806 self.assertEqual(dco.decompress(zlib9), HAMLET_SCENE)
807
808 co = zlib.compressobj(level=1, wbits=-15)
809 deflate15 = co.compress(HAMLET_SCENE) + co.flush()
810 self.assertEqual(zlib.decompress(deflate15, -15), HAMLET_SCENE)
811 dco = zlib.decompressobj(wbits=-15)
812 self.assertEqual(dco.decompress(deflate15), HAMLET_SCENE)
813
814 co = zlib.compressobj(level=1, wbits=-9)
815 deflate9 = co.compress(HAMLET_SCENE) + co.flush()
816 self.assertEqual(zlib.decompress(deflate9, -9), HAMLET_SCENE)
817 self.assertEqual(zlib.decompress(deflate9, -15), HAMLET_SCENE)
818 dco = zlib.decompressobj(wbits=-9)
819 self.assertEqual(dco.decompress(deflate9), HAMLET_SCENE)
820
821 co = zlib.compressobj(level=1, wbits=16 + 15)
822 gzip = co.compress(HAMLET_SCENE) + co.flush()
823 self.assertEqual(zlib.decompress(gzip, 16 + 15), HAMLET_SCENE)
824 self.assertEqual(zlib.decompress(gzip, 32 + 15), HAMLET_SCENE)
825 dco = zlib.decompressobj(32 + 15)
826 self.assertEqual(dco.decompress(gzip), HAMLET_SCENE)
827
Antoine Pitrou89562712010-05-07 17:04:02 +0000828
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000829def choose_lines(source, number, seed=None, generator=random):
830 """Return a list of number lines randomly chosen from the source"""
831 if seed is not None:
832 generator.seed(seed)
833 sources = source.split('\n')
834 return [generator.choice(sources) for n in range(number)]
835
836
Guido van Rossum776152b2007-05-22 22:44:07 +0000837HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000838LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000839
840 O, fear me not.
841 I stay too long: but here my father comes.
842
843 Enter POLONIUS
844
845 A double blessing is a double grace,
846 Occasion smiles upon a second leave.
847
Fred Drake004d5e62000-10-23 17:22:08 +0000848LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000849
850 Yet here, Laertes! aboard, aboard, for shame!
851 The wind sits in the shoulder of your sail,
852 And you are stay'd for. There; my blessing with thee!
853 And these few precepts in thy memory
854 See thou character. Give thy thoughts no tongue,
855 Nor any unproportioned thought his act.
856 Be thou familiar, but by no means vulgar.
857 Those friends thou hast, and their adoption tried,
858 Grapple them to thy soul with hoops of steel;
859 But do not dull thy palm with entertainment
860 Of each new-hatch'd, unfledged comrade. Beware
861 Of entrance to a quarrel, but being in,
862 Bear't that the opposed may beware of thee.
863 Give every man thy ear, but few thy voice;
864 Take each man's censure, but reserve thy judgment.
865 Costly thy habit as thy purse can buy,
866 But not express'd in fancy; rich, not gaudy;
867 For the apparel oft proclaims the man,
868 And they in France of the best rank and station
869 Are of a most select and generous chief in that.
870 Neither a borrower nor a lender be;
871 For loan oft loses both itself and friend,
872 And borrowing dulls the edge of husbandry.
873 This above all: to thine ownself be true,
874 And it must follow, as the night the day,
875 Thou canst not then be false to any man.
876 Farewell: my blessing season this in thee!
877
Fred Drake004d5e62000-10-23 17:22:08 +0000878LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000879
880 Most humbly do I take my leave, my lord.
881
Fred Drake004d5e62000-10-23 17:22:08 +0000882LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000883
884 The time invites you; go; your servants tend.
885
Fred Drake004d5e62000-10-23 17:22:08 +0000886LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000887
888 Farewell, Ophelia; and remember well
889 What I have said to you.
890
Fred Drake004d5e62000-10-23 17:22:08 +0000891OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000892
893 'Tis in my memory lock'd,
894 And you yourself shall keep the key of it.
895
Fred Drake004d5e62000-10-23 17:22:08 +0000896LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000897
898 Farewell.
899"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000900
901
Martin Pantere99e9772015-11-20 08:13:35 +0000902class CustomInt:
Serhiy Storchaka6a44f6e2019-02-25 17:57:58 +0200903 def __index__(self):
Martin Pantere99e9772015-11-20 08:13:35 +0000904 return 100
905
906
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000907if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500908 unittest.main()