blob: cb0610837baafc0ddf5e565be861229b2750510f [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)
Erlend Egeberg Aasland0a3452e2021-06-24 01:46:25 +0200135 support.check_disallow_instantiation(self, type(zlib.compressobj()))
136 support.check_disallow_instantiation(self, type(zlib.decompressobj()))
Erlend Egeberg Aasland9746cda2021-04-30 16:04:57 +0200137
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000138
Antoine Pitrou89562712010-05-07 17:04:02 +0000139class BaseCompressTestCase(object):
140 def check_big_compress_buffer(self, size, compress_func):
141 _1M = 1024 * 1024
Victor Stinner8c663fd2017-11-08 14:44:44 -0800142 # Generate 10 MiB worth of random, and expand it by repeating it.
Antoine Pitrou89562712010-05-07 17:04:02 +0000143 # The assumption is that zlib's memory is not big enough to exploit
144 # such spread out redundancy.
Victor Stinner87502dd2020-04-17 22:54:38 +0200145 data = random.randbytes(_1M * 10)
Antoine Pitrou89562712010-05-07 17:04:02 +0000146 data = data * (size // len(data) + 1)
147 try:
148 compress_func(data)
149 finally:
150 # Release memory
151 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000152
Antoine Pitrou89562712010-05-07 17:04:02 +0000153 def check_big_decompress_buffer(self, size, decompress_func):
154 data = b'x' * size
155 try:
156 compressed = zlib.compress(data, 1)
157 finally:
158 # Release memory
159 data = None
160 data = decompress_func(compressed)
161 # Sanity check
162 try:
163 self.assertEqual(len(data), size)
164 self.assertEqual(len(data.strip(b'x')), 0)
165 finally:
166 data = None
167
168
169class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000170 # Test compression in one go (whole message compression)
171 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000172 x = zlib.compress(HAMLET_SCENE)
173 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000174
Martin Panter1fe0d132016-02-10 10:06:36 +0000175 def test_keywords(self):
Serhiy Storchaka95657cd2016-06-25 22:43:05 +0300176 x = zlib.compress(HAMLET_SCENE, level=3)
Martin Panter1fe0d132016-02-10 10:06:36 +0000177 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Serhiy Storchaka95657cd2016-06-25 22:43:05 +0300178 with self.assertRaises(TypeError):
179 zlib.compress(data=HAMLET_SCENE, level=3)
Serhiy Storchaka15f32282016-08-15 10:06:16 +0300180 self.assertEqual(zlib.decompress(x,
181 wbits=zlib.MAX_WBITS,
182 bufsize=zlib.DEF_BUF_SIZE),
183 HAMLET_SCENE)
Martin Panter1fe0d132016-02-10 10:06:36 +0000184
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000185 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000186 # compress more data
187 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000188 x = zlib.compress(data)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000189 self.assertEqual(zlib.compress(bytearray(data)), x)
190 for ob in x, bytearray(x):
191 self.assertEqual(zlib.decompress(ob), data)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000192
Antoine Pitrou53b21662010-05-11 23:46:02 +0000193 def test_incomplete_stream(self):
Martin Panter6245cb32016-04-15 02:14:19 +0000194 # A useful error message is given
Antoine Pitrou53b21662010-05-11 23:46:02 +0000195 x = zlib.compress(HAMLET_SCENE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000196 self.assertRaisesRegex(zlib.error,
Antoine Pitrou53b21662010-05-11 23:46:02 +0000197 "Error -5 while decompressing data: incomplete or truncated stream",
198 zlib.decompress, x[:-1])
199
Antoine Pitrou89562712010-05-07 17:04:02 +0000200 # Memory use of the following functions takes into account overallocation
201
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200202 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000203 def test_big_compress_buffer(self, size):
204 compress = lambda s: zlib.compress(s, 1)
205 self.check_big_compress_buffer(size, compress)
206
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200207 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000208 def test_big_decompress_buffer(self, size):
209 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000210
Martin Pantere99e9772015-11-20 08:13:35 +0000211 @bigmemtest(size=_4G, memuse=1)
212 def test_large_bufsize(self, size):
213 # Test decompress(bufsize) parameter greater than the internal limit
214 data = HAMLET_SCENE * 10
215 compressed = zlib.compress(data, 1)
216 self.assertEqual(zlib.decompress(compressed, 15, size), data)
217
218 def test_custom_bufsize(self):
219 data = HAMLET_SCENE * 10
220 compressed = zlib.compress(data, 1)
221 self.assertEqual(zlib.decompress(compressed, 15, CustomInt()), data)
222
Martin Panter84544c12016-07-23 03:02:07 +0000223 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
224 @bigmemtest(size=_4G + 100, memuse=4)
225 def test_64bit_compress(self, size):
226 data = b'x' * size
227 try:
228 comp = zlib.compress(data, 0)
229 self.assertEqual(zlib.decompress(comp), data)
230 finally:
231 comp = data = None
232
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000233
Antoine Pitrou89562712010-05-07 17:04:02 +0000234class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000235 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000236 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000237 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000238 datasrc = HAMLET_SCENE * 128
239 datazip = zlib.compress(datasrc)
240 # should compress both bytes and bytearray data
241 for data in (datasrc, bytearray(datasrc)):
242 co = zlib.compressobj()
243 x1 = co.compress(data)
244 x2 = co.flush()
245 self.assertRaises(zlib.error, co.flush) # second flush should not work
246 self.assertEqual(x1 + x2, datazip)
247 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
248 dco = zlib.decompressobj()
249 y1 = dco.decompress(v1 + v2)
250 y2 = dco.flush()
251 self.assertEqual(data, y1 + y2)
252 self.assertIsInstance(dco.unconsumed_tail, bytes)
253 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000254
Serhiy Storchaka15f32282016-08-15 10:06:16 +0300255 def test_keywords(self):
256 level = 2
257 method = zlib.DEFLATED
258 wbits = -12
259 memLevel = 9
260 strategy = zlib.Z_FILTERED
261 co = zlib.compressobj(level=level,
262 method=method,
263 wbits=wbits,
264 memLevel=memLevel,
265 strategy=strategy,
266 zdict=b"")
267 do = zlib.decompressobj(wbits=wbits, zdict=b"")
268 with self.assertRaises(TypeError):
269 co.compress(data=HAMLET_SCENE)
270 with self.assertRaises(TypeError):
271 do.decompress(data=zlib.compress(HAMLET_SCENE))
272 x = co.compress(HAMLET_SCENE) + co.flush()
273 y = do.decompress(x, max_length=len(HAMLET_SCENE)) + do.flush()
274 self.assertEqual(HAMLET_SCENE, y)
275
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000276 def test_compressoptions(self):
277 # specify lots of options to compressobj()
278 level = 2
279 method = zlib.DEFLATED
280 wbits = -12
Martin Panterbf19d162015-09-09 01:01:13 +0000281 memLevel = 9
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000282 strategy = zlib.Z_FILTERED
Martin Panterbf19d162015-09-09 01:01:13 +0000283 co = zlib.compressobj(level, method, wbits, memLevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000284 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000285 x2 = co.flush()
286 dco = zlib.decompressobj(wbits)
287 y1 = dco.decompress(x1 + x2)
288 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000289 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000290
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000291 def test_compressincremental(self):
292 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000293 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000294 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000295 bufs = []
296 for i in range(0, len(data), 256):
297 bufs.append(co.compress(data[i:i+256]))
298 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000299 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000300
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000301 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000302 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000303 y2 = dco.flush()
304 self.assertEqual(data, y1 + y2)
305
Neil Schemenauer6412b122004-06-05 19:34:28 +0000306 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000307 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000308 source = source or HAMLET_SCENE
309 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000310 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000311 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000312 for i in range(0, len(data), cx):
313 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000314 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000315 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000316
Gregory P. Smith693fc462008-09-06 20:13:06 +0000317 decombuf = zlib.decompress(combuf)
318 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000319 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000320
321 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000322
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000323 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000324 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000325 for i in range(0, len(combuf), dcx):
326 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000327 self.assertEqual(b'', dco.unconsumed_tail, ########
328 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000329 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000330 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000331 if flush:
332 bufs.append(dco.flush())
333 else:
334 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000335 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000336 if chunk:
337 bufs.append(chunk)
338 else:
339 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000340 self.assertEqual(b'', dco.unconsumed_tail, ########
341 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000342 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000343 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000344 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000345 # Failure means: "decompressobj with init options failed"
346
Neil Schemenauer6412b122004-06-05 19:34:28 +0000347 def test_decompincflush(self):
348 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000349
Neil Schemenauer6412b122004-06-05 19:34:28 +0000350 def test_decompimax(self, source=None, cx=256, dcx=64):
351 # compress in steps, decompress in length-restricted steps
352 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000353 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000354 data = source * 128
355 co = zlib.compressobj()
356 bufs = []
357 for i in range(0, len(data), cx):
358 bufs.append(co.compress(data[i:i+cx]))
359 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000360 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000361 self.assertEqual(data, zlib.decompress(combuf),
362 'compressed data failure')
363
364 dco = zlib.decompressobj()
365 bufs = []
366 cb = combuf
367 while cb:
368 #max_length = 1 + len(cb)//10
369 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000370 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000371 'chunk too big (%d>%d)' % (len(chunk), dcx))
372 bufs.append(chunk)
373 cb = dco.unconsumed_tail
374 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000375 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000376
377 def test_decompressmaxlen(self, flush=False):
378 # Check a decompression object with max_length specified
379 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000380 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000381 bufs = []
382 for i in range(0, len(data), 256):
383 bufs.append(co.compress(data[i:i+256]))
384 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000385 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000386 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000387 'compressed data failure')
388
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000389 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000390 bufs = []
391 cb = combuf
392 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000393 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000394 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000395 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000396 'chunk too big (%d>%d)' % (len(chunk),max_length))
397 bufs.append(chunk)
398 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000399 if flush:
400 bufs.append(dco.flush())
401 else:
402 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000403 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000404 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000405 'chunk too big (%d>%d)' % (len(chunk),max_length))
406 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000407 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000408
Neil Schemenauer6412b122004-06-05 19:34:28 +0000409 def test_decompressmaxlenflush(self):
410 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000411
412 def test_maxlenmisc(self):
413 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000414 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000415 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000416 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000417
Martin Pantere99e9772015-11-20 08:13:35 +0000418 def test_maxlen_large(self):
419 # Sizes up to sys.maxsize should be accepted, although zlib is
420 # internally limited to expressing sizes with unsigned int
421 data = HAMLET_SCENE * 10
422 self.assertGreater(len(data), zlib.DEF_BUF_SIZE)
423 compressed = zlib.compress(data, 1)
424 dco = zlib.decompressobj()
425 self.assertEqual(dco.decompress(compressed, sys.maxsize), data)
426
427 def test_maxlen_custom(self):
428 data = HAMLET_SCENE * 10
429 compressed = zlib.compress(data, 1)
430 dco = zlib.decompressobj()
431 self.assertEqual(dco.decompress(compressed, CustomInt()), data[:100])
432
Nadeem Vawda7619e882011-05-14 14:05:20 +0200433 def test_clear_unconsumed_tail(self):
434 # Issue #12050: calling decompress() without providing max_length
435 # should clear the unconsumed_tail attribute.
436 cdata = b"x\x9cKLJ\x06\x00\x02M\x01" # "abc"
437 dco = zlib.decompressobj()
438 ddata = dco.decompress(cdata, 1)
439 ddata += dco.decompress(dco.unconsumed_tail)
440 self.assertEqual(dco.unconsumed_tail, b"")
441
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000442 def test_flushes(self):
443 # Test flush() with the various options, using all the
444 # different levels in order to provide more variations.
Xiang Zhangbc3f2282018-03-07 13:05:37 +0800445 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH',
Steve Dower57675092018-09-24 07:44:50 -0400446 'Z_PARTIAL_FLUSH']
447
448 ver = tuple(int(v) for v in zlib.ZLIB_RUNTIME_VERSION.split('.'))
449 # Z_BLOCK has a known failure prior to 1.2.5.3
450 if ver >= (1, 2, 5, 3):
451 sync_opt.append('Z_BLOCK')
452
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000453 sync_opt = [getattr(zlib, opt) for opt in sync_opt
454 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000455 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000456
457 for sync in sync_opt:
458 for level in range(10):
Steve Dower57675092018-09-24 07:44:50 -0400459 try:
460 obj = zlib.compressobj( level )
461 a = obj.compress( data[:3000] )
462 b = obj.flush( sync )
463 c = obj.compress( data[3000:] )
464 d = obj.flush()
465 except:
466 print("Error for flush mode={}, level={}"
467 .format(sync, level))
468 raise
Guido van Rossum776152b2007-05-22 22:44:07 +0000469 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000470 data, ("Decompress failed: flush "
471 "mode=%i, level=%i") % (sync, level))
472 del obj
473
Serhiy Storchaka43767632013-11-03 21:31:38 +0200474 @unittest.skipUnless(hasattr(zlib, 'Z_SYNC_FLUSH'),
475 'requires zlib.Z_SYNC_FLUSH')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000476 def test_odd_flush(self):
477 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
478 import random
Serhiy Storchaka43767632013-11-03 21:31:38 +0200479 # Testing on 17K of "random" data
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000480
Serhiy Storchaka43767632013-11-03 21:31:38 +0200481 # Create compressor and decompressor objects
482 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
483 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000484
Serhiy Storchaka43767632013-11-03 21:31:38 +0200485 # Try 17K of data
486 # generate random data stream
487 try:
488 # In 2.3 and later, WichmannHill is the RNG of the bug report
489 gen = random.WichmannHill()
490 except AttributeError:
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000491 try:
Serhiy Storchaka43767632013-11-03 21:31:38 +0200492 # 2.2 called it Random
493 gen = random.Random()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000494 except AttributeError:
Serhiy Storchaka43767632013-11-03 21:31:38 +0200495 # others might simply have a single RNG
496 gen = random
497 gen.seed(1)
Victor Stinner87502dd2020-04-17 22:54:38 +0200498 data = gen.randbytes(17 * 1024)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000499
Serhiy Storchaka43767632013-11-03 21:31:38 +0200500 # compress, sync-flush, and decompress
501 first = co.compress(data)
502 second = co.flush(zlib.Z_SYNC_FLUSH)
503 expanded = dco.decompress(first + second)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000504
Serhiy Storchaka43767632013-11-03 21:31:38 +0200505 # if decompressed data is different from the input data, choke.
506 self.assertEqual(expanded, data, "17K random source doesn't match")
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000507
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000508 def test_empty_flush(self):
509 # Test that calling .flush() on unused objects works.
510 # (Bug #1083110 -- calling .flush() on decompress objects
511 # caused a core dump.)
512
513 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000514 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000515 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000516 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000517
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200518 def test_dictionary(self):
519 h = HAMLET_SCENE
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200520 # Build a simulated dictionary out of the words in HAMLET.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200521 words = h.split()
522 random.shuffle(words)
523 zdict = b''.join(words)
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200524 # Use it to compress HAMLET.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200525 co = zlib.compressobj(zdict=zdict)
526 cd = co.compress(h) + co.flush()
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200527 # Verify that it will decompress with the dictionary.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200528 dco = zlib.decompressobj(zdict=zdict)
529 self.assertEqual(dco.decompress(cd) + dco.flush(), h)
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200530 # Verify that it fails when not given the dictionary.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200531 dco = zlib.decompressobj()
532 self.assertRaises(zlib.error, dco.decompress, cd)
533
534 def test_dictionary_streaming(self):
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200535 # This simulates the reuse of a compressor object for compressing
536 # several separate data streams.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200537 co = zlib.compressobj(zdict=HAMLET_SCENE)
538 do = zlib.decompressobj(zdict=HAMLET_SCENE)
539 piece = HAMLET_SCENE[1000:1500]
540 d0 = co.compress(piece) + co.flush(zlib.Z_SYNC_FLUSH)
541 d1 = co.compress(piece[100:]) + co.flush(zlib.Z_SYNC_FLUSH)
542 d2 = co.compress(piece[:-100]) + co.flush(zlib.Z_SYNC_FLUSH)
543 self.assertEqual(do.decompress(d0), piece)
544 self.assertEqual(do.decompress(d1), piece[100:])
545 self.assertEqual(do.decompress(d2), piece[:-100])
546
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000547 def test_decompress_incomplete_stream(self):
548 # This is 'foo', deflated
549 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
550 # For the record
551 self.assertEqual(zlib.decompress(x), b'foo')
552 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
553 # Omitting the stream end works with decompressor objects
554 # (see issue #8672).
555 dco = zlib.decompressobj()
556 y = dco.decompress(x[:-5])
557 y += dco.flush()
558 self.assertEqual(y, b'foo')
559
Nadeem Vawda1c385462011-08-13 15:22:40 +0200560 def test_decompress_eof(self):
561 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
562 dco = zlib.decompressobj()
563 self.assertFalse(dco.eof)
564 dco.decompress(x[:-5])
565 self.assertFalse(dco.eof)
566 dco.decompress(x[-5:])
567 self.assertTrue(dco.eof)
568 dco.flush()
569 self.assertTrue(dco.eof)
570
571 def test_decompress_eof_incomplete_stream(self):
572 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
573 dco = zlib.decompressobj()
574 self.assertFalse(dco.eof)
575 dco.decompress(x[:-5])
576 self.assertFalse(dco.eof)
577 dco.flush()
578 self.assertFalse(dco.eof)
579
Nadeem Vawda39079942012-11-05 00:37:42 +0100580 def test_decompress_unused_data(self):
581 # Repeated calls to decompress() after EOF should accumulate data in
582 # dco.unused_data, instead of just storing the arg to the last call.
Nadeem Vawdaee7889d2012-11-11 02:14:36 +0100583 source = b'abcdefghijklmnopqrstuvwxyz'
584 remainder = b'0123456789'
585 y = zlib.compress(source)
586 x = y + remainder
587 for maxlen in 0, 1000:
588 for step in 1, 2, len(y), len(x):
589 dco = zlib.decompressobj()
590 data = b''
591 for i in range(0, len(x), step):
592 if i < len(y):
593 self.assertEqual(dco.unused_data, b'')
594 if maxlen == 0:
595 data += dco.decompress(x[i : i + step])
596 self.assertEqual(dco.unconsumed_tail, b'')
597 else:
598 data += dco.decompress(
599 dco.unconsumed_tail + x[i : i + step], maxlen)
600 data += dco.flush()
Nadeem Vawdadd1253a2012-11-11 02:21:22 +0100601 self.assertTrue(dco.eof)
Nadeem Vawdaee7889d2012-11-11 02:14:36 +0100602 self.assertEqual(data, source)
603 self.assertEqual(dco.unconsumed_tail, b'')
604 self.assertEqual(dco.unused_data, remainder)
Nadeem Vawda39079942012-11-05 00:37:42 +0100605
Martin Panter3f0ee832016-06-05 10:48:34 +0000606 # issue27164
607 def test_decompress_raw_with_dictionary(self):
608 zdict = b'abcdefghijklmnopqrstuvwxyz'
609 co = zlib.compressobj(wbits=-zlib.MAX_WBITS, zdict=zdict)
610 comp = co.compress(zdict) + co.flush()
611 dco = zlib.decompressobj(wbits=-zlib.MAX_WBITS, zdict=zdict)
612 uncomp = dco.decompress(comp) + dco.flush()
613 self.assertEqual(zdict, uncomp)
614
Nadeem Vawda7ee95552012-11-11 03:15:32 +0100615 def test_flush_with_freed_input(self):
616 # Issue #16411: decompressor accesses input to last decompress() call
617 # in flush(), even if this object has been freed in the meanwhile.
618 input1 = b'abcdefghijklmnopqrstuvwxyz'
619 input2 = b'QWERTYUIOPASDFGHJKLZXCVBNM'
620 data = zlib.compress(input1)
621 dco = zlib.decompressobj()
622 dco.decompress(data, 1)
623 del data
624 data = zlib.compress(input2)
625 self.assertEqual(dco.flush(), input1[1:])
626
Martin Pantere99e9772015-11-20 08:13:35 +0000627 @bigmemtest(size=_4G, memuse=1)
628 def test_flush_large_length(self, size):
629 # Test flush(length) parameter greater than internal limit UINT_MAX
630 input = HAMLET_SCENE * 10
631 data = zlib.compress(input, 1)
632 dco = zlib.decompressobj()
633 dco.decompress(data, 1)
634 self.assertEqual(dco.flush(size), input[1:])
635
636 def test_flush_custom_length(self):
637 input = HAMLET_SCENE * 10
638 data = zlib.compress(input, 1)
639 dco = zlib.decompressobj()
640 dco.decompress(data, 1)
641 self.assertEqual(dco.flush(CustomInt()), input[1:])
642
Serhiy Storchaka43767632013-11-03 21:31:38 +0200643 @requires_Compress_copy
644 def test_compresscopy(self):
645 # Test copying a compression object
646 data0 = HAMLET_SCENE
647 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600648 for func in lambda c: c.copy(), copy.copy, copy.deepcopy:
649 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
650 bufs0 = []
651 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000652
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600653 c1 = func(c0)
654 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000655
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600656 bufs0.append(c0.compress(data0))
657 bufs0.append(c0.flush())
658 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000659
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600660 bufs1.append(c1.compress(data1))
661 bufs1.append(c1.flush())
662 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000663
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600664 self.assertEqual(zlib.decompress(s0),data0+data0)
665 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000666
Serhiy Storchaka43767632013-11-03 21:31:38 +0200667 @requires_Compress_copy
668 def test_badcompresscopy(self):
669 # Test copying a compression object in an inconsistent state
670 c = zlib.compressobj()
671 c.compress(HAMLET_SCENE)
672 c.flush()
673 self.assertRaises(ValueError, c.copy)
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600674 self.assertRaises(ValueError, copy.copy, c)
675 self.assertRaises(ValueError, copy.deepcopy, c)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000676
Serhiy Storchaka43767632013-11-03 21:31:38 +0200677 @requires_Decompress_copy
678 def test_decompresscopy(self):
679 # Test copying a decompression object
680 data = HAMLET_SCENE
681 comp = zlib.compress(data)
682 # Test type of return value
683 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000684
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600685 for func in lambda c: c.copy(), copy.copy, copy.deepcopy:
686 d0 = zlib.decompressobj()
687 bufs0 = []
688 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000689
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600690 d1 = func(d0)
691 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000692
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600693 bufs0.append(d0.decompress(comp[32:]))
694 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000695
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600696 bufs1.append(d1.decompress(comp[32:]))
697 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000698
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600699 self.assertEqual(s0,s1)
700 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000701
Serhiy Storchaka43767632013-11-03 21:31:38 +0200702 @requires_Decompress_copy
703 def test_baddecompresscopy(self):
704 # Test copying a compression object in an inconsistent state
705 data = zlib.compress(HAMLET_SCENE)
706 d = zlib.decompressobj()
707 d.decompress(data)
708 d.flush()
709 self.assertRaises(ValueError, d.copy)
Zackery Spytzd2cbfff2018-06-27 12:04:51 -0600710 self.assertRaises(ValueError, copy.copy, d)
711 self.assertRaises(ValueError, copy.deepcopy, d)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000712
Serhiy Storchakad7a44152015-11-12 11:23:04 +0200713 def test_compresspickle(self):
714 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
715 with self.assertRaises((TypeError, pickle.PicklingError)):
716 pickle.dumps(zlib.compressobj(zlib.Z_BEST_COMPRESSION), proto)
717
718 def test_decompresspickle(self):
719 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
720 with self.assertRaises((TypeError, pickle.PicklingError)):
721 pickle.dumps(zlib.decompressobj(), proto)
722
Antoine Pitrou89562712010-05-07 17:04:02 +0000723 # Memory use of the following functions takes into account overallocation
724
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200725 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000726 def test_big_compress_buffer(self, size):
727 c = zlib.compressobj(1)
728 compress = lambda s: c.compress(s) + c.flush()
729 self.check_big_compress_buffer(size, compress)
730
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200731 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000732 def test_big_decompress_buffer(self, size):
733 d = zlib.decompressobj()
734 decompress = lambda s: d.decompress(s) + d.flush()
735 self.check_big_decompress_buffer(size, decompress)
736
Martin Panter84544c12016-07-23 03:02:07 +0000737 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
738 @bigmemtest(size=_4G + 100, memuse=4)
739 def test_64bit_compress(self, size):
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200740 data = b'x' * size
Martin Panter84544c12016-07-23 03:02:07 +0000741 co = zlib.compressobj(0)
742 do = zlib.decompressobj()
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200743 try:
Martin Panter84544c12016-07-23 03:02:07 +0000744 comp = co.compress(data) + co.flush()
745 uncomp = do.decompress(comp) + do.flush()
746 self.assertEqual(uncomp, data)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200747 finally:
Martin Panter84544c12016-07-23 03:02:07 +0000748 comp = uncomp = data = None
749
750 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
751 @bigmemtest(size=_4G + 100, memuse=3)
752 def test_large_unused_data(self, size):
753 data = b'abcdefghijklmnop'
754 unused = b'x' * size
755 comp = zlib.compress(data) + unused
756 do = zlib.decompressobj()
757 try:
758 uncomp = do.decompress(comp) + do.flush()
759 self.assertEqual(unused, do.unused_data)
760 self.assertEqual(uncomp, data)
761 finally:
762 unused = comp = do = None
763
764 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
765 @bigmemtest(size=_4G + 100, memuse=5)
766 def test_large_unconsumed_tail(self, size):
767 data = b'x' * size
768 do = zlib.decompressobj()
769 try:
770 comp = zlib.compress(data, 0)
771 uncomp = do.decompress(comp, 1) + do.flush()
772 self.assertEqual(uncomp, data)
773 self.assertEqual(do.unconsumed_tail, b'')
774 finally:
775 comp = uncomp = data = None
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200776
Martin Panter0fdf41d2016-05-27 07:32:11 +0000777 def test_wbits(self):
Martin Panterc618ae82016-05-27 11:20:21 +0000778 # wbits=0 only supported since zlib v1.2.3.5
779 # Register "1.2.3" as "1.2.3.0"
pmp-p4c7108a2018-02-19 04:45:11 +0100780 # or "1.2.0-linux","1.2.0.f","1.2.0.f-linux"
781 v = zlib.ZLIB_RUNTIME_VERSION.split('-', 1)[0].split('.')
782 if len(v) < 4:
783 v.append('0')
784 elif not v[-1].isnumeric():
785 v[-1] = '0'
786
787 v = tuple(map(int, v))
788 supports_wbits_0 = v >= (1, 2, 3, 5)
Martin Panterc618ae82016-05-27 11:20:21 +0000789
Martin Panter0fdf41d2016-05-27 07:32:11 +0000790 co = zlib.compressobj(level=1, wbits=15)
791 zlib15 = co.compress(HAMLET_SCENE) + co.flush()
792 self.assertEqual(zlib.decompress(zlib15, 15), HAMLET_SCENE)
Martin Panterc618ae82016-05-27 11:20:21 +0000793 if supports_wbits_0:
794 self.assertEqual(zlib.decompress(zlib15, 0), HAMLET_SCENE)
Martin Panter0fdf41d2016-05-27 07:32:11 +0000795 self.assertEqual(zlib.decompress(zlib15, 32 + 15), HAMLET_SCENE)
796 with self.assertRaisesRegex(zlib.error, 'invalid window size'):
797 zlib.decompress(zlib15, 14)
798 dco = zlib.decompressobj(wbits=32 + 15)
799 self.assertEqual(dco.decompress(zlib15), HAMLET_SCENE)
800 dco = zlib.decompressobj(wbits=14)
801 with self.assertRaisesRegex(zlib.error, 'invalid window size'):
802 dco.decompress(zlib15)
803
804 co = zlib.compressobj(level=1, wbits=9)
805 zlib9 = co.compress(HAMLET_SCENE) + co.flush()
806 self.assertEqual(zlib.decompress(zlib9, 9), HAMLET_SCENE)
807 self.assertEqual(zlib.decompress(zlib9, 15), HAMLET_SCENE)
Martin Panterc618ae82016-05-27 11:20:21 +0000808 if supports_wbits_0:
809 self.assertEqual(zlib.decompress(zlib9, 0), HAMLET_SCENE)
Martin Panter0fdf41d2016-05-27 07:32:11 +0000810 self.assertEqual(zlib.decompress(zlib9, 32 + 9), HAMLET_SCENE)
811 dco = zlib.decompressobj(wbits=32 + 9)
812 self.assertEqual(dco.decompress(zlib9), HAMLET_SCENE)
813
814 co = zlib.compressobj(level=1, wbits=-15)
815 deflate15 = co.compress(HAMLET_SCENE) + co.flush()
816 self.assertEqual(zlib.decompress(deflate15, -15), HAMLET_SCENE)
817 dco = zlib.decompressobj(wbits=-15)
818 self.assertEqual(dco.decompress(deflate15), HAMLET_SCENE)
819
820 co = zlib.compressobj(level=1, wbits=-9)
821 deflate9 = co.compress(HAMLET_SCENE) + co.flush()
822 self.assertEqual(zlib.decompress(deflate9, -9), HAMLET_SCENE)
823 self.assertEqual(zlib.decompress(deflate9, -15), HAMLET_SCENE)
824 dco = zlib.decompressobj(wbits=-9)
825 self.assertEqual(dco.decompress(deflate9), HAMLET_SCENE)
826
827 co = zlib.compressobj(level=1, wbits=16 + 15)
828 gzip = co.compress(HAMLET_SCENE) + co.flush()
829 self.assertEqual(zlib.decompress(gzip, 16 + 15), HAMLET_SCENE)
830 self.assertEqual(zlib.decompress(gzip, 32 + 15), HAMLET_SCENE)
831 dco = zlib.decompressobj(32 + 15)
832 self.assertEqual(dco.decompress(gzip), HAMLET_SCENE)
833
Antoine Pitrou89562712010-05-07 17:04:02 +0000834
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000835def choose_lines(source, number, seed=None, generator=random):
836 """Return a list of number lines randomly chosen from the source"""
837 if seed is not None:
838 generator.seed(seed)
839 sources = source.split('\n')
840 return [generator.choice(sources) for n in range(number)]
841
842
Guido van Rossum776152b2007-05-22 22:44:07 +0000843HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000844LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000845
846 O, fear me not.
847 I stay too long: but here my father comes.
848
849 Enter POLONIUS
850
851 A double blessing is a double grace,
852 Occasion smiles upon a second leave.
853
Fred Drake004d5e62000-10-23 17:22:08 +0000854LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000855
856 Yet here, Laertes! aboard, aboard, for shame!
857 The wind sits in the shoulder of your sail,
858 And you are stay'd for. There; my blessing with thee!
859 And these few precepts in thy memory
860 See thou character. Give thy thoughts no tongue,
861 Nor any unproportioned thought his act.
862 Be thou familiar, but by no means vulgar.
863 Those friends thou hast, and their adoption tried,
864 Grapple them to thy soul with hoops of steel;
865 But do not dull thy palm with entertainment
866 Of each new-hatch'd, unfledged comrade. Beware
867 Of entrance to a quarrel, but being in,
868 Bear't that the opposed may beware of thee.
869 Give every man thy ear, but few thy voice;
870 Take each man's censure, but reserve thy judgment.
871 Costly thy habit as thy purse can buy,
872 But not express'd in fancy; rich, not gaudy;
873 For the apparel oft proclaims the man,
874 And they in France of the best rank and station
875 Are of a most select and generous chief in that.
876 Neither a borrower nor a lender be;
877 For loan oft loses both itself and friend,
878 And borrowing dulls the edge of husbandry.
879 This above all: to thine ownself be true,
880 And it must follow, as the night the day,
881 Thou canst not then be false to any man.
882 Farewell: my blessing season this in thee!
883
Fred Drake004d5e62000-10-23 17:22:08 +0000884LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000885
886 Most humbly do I take my leave, my lord.
887
Fred Drake004d5e62000-10-23 17:22:08 +0000888LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000889
890 The time invites you; go; your servants tend.
891
Fred Drake004d5e62000-10-23 17:22:08 +0000892LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000893
894 Farewell, Ophelia; and remember well
895 What I have said to you.
896
Fred Drake004d5e62000-10-23 17:22:08 +0000897OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000898
899 'Tis in my memory lock'd,
900 And you yourself shall keep the key of it.
901
Fred Drake004d5e62000-10-23 17:22:08 +0000902LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000903
904 Farewell.
905"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000906
907
Martin Pantere99e9772015-11-20 08:13:35 +0000908class CustomInt:
Serhiy Storchaka6a44f6e2019-02-25 17:57:58 +0200909 def __index__(self):
Martin Pantere99e9772015-11-20 08:13:35 +0000910 return 100
911
912
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000913if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500914 unittest.main()