blob: e67bee97cb3d3be55d7870ba0efd4a8a7d592c93 [file] [log] [blame]
Guido van Rossum7d9ea502003-02-03 20:45:52 +00001import unittest
Benjamin Petersonee8712c2008-05-20 21:35:26 +00002from test import support
Christian Heimesd5e2b6f2008-03-19 21:50:51 +00003import binascii
Serhiy Storchakad7a44152015-11-12 11:23:04 +02004import pickle
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00005import random
Antoine Pitrouf3d22752011-02-21 18:09:00 +00006import sys
Antoine Pitrou94190bb2011-10-04 10:22:36 +02007from test.support import bigmemtest, _1G, _4G
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00008
R. David Murraya21e4ca2009-03-31 23:16:50 +00009zlib = support.import_module('zlib')
10
Serhiy Storchaka43767632013-11-03 21:31:38 +020011requires_Compress_copy = unittest.skipUnless(
12 hasattr(zlib.compressobj(), "copy"),
13 'requires Compress.copy()')
14requires_Decompress_copy = unittest.skipUnless(
15 hasattr(zlib.decompressobj(), "copy"),
16 'requires Decompress.copy()')
17
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000018
Nadeem Vawda64d25dd2011-09-12 00:04:13 +020019class VersionTestCase(unittest.TestCase):
20
21 def test_library_version(self):
Nadeem Vawda131c7072012-01-25 23:16:50 +020022 # Test that the major version of the actual library in use matches the
23 # major version that we were compiled against. We can't guarantee that
24 # the minor versions will match (even on the machine on which the module
25 # was compiled), and the API is stable between minor versions, so
Nadeem Vawdad770fe42012-01-28 17:32:47 +020026 # testing only the major versions avoids spurious failures.
Nadeem Vawda131c7072012-01-25 23:16:50 +020027 self.assertEqual(zlib.ZLIB_RUNTIME_VERSION[0], zlib.ZLIB_VERSION[0])
Nadeem Vawda64d25dd2011-09-12 00:04:13 +020028
29
Guido van Rossum7d9ea502003-02-03 20:45:52 +000030class ChecksumTestCase(unittest.TestCase):
31 # checksum test cases
32 def test_crc32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000033 self.assertEqual(zlib.crc32(b""), zlib.crc32(b"", 0))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000034 self.assertTrue(zlib.crc32(b"abc", 0xffffffff))
Andrew M. Kuchlingfcfc8d52001-08-10 15:50:11 +000035
Guido van Rossum7d9ea502003-02-03 20:45:52 +000036 def test_crc32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000037 self.assertEqual(zlib.crc32(b"", 0), 0)
38 self.assertEqual(zlib.crc32(b"", 1), 1)
39 self.assertEqual(zlib.crc32(b"", 432), 432)
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000040
Guido van Rossum7d9ea502003-02-03 20:45:52 +000041 def test_adler32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000042 self.assertEqual(zlib.adler32(b""), zlib.adler32(b"", 1))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000043 self.assertTrue(zlib.adler32(b"abc", 0xffffffff))
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000044
Guido van Rossum7d9ea502003-02-03 20:45:52 +000045 def test_adler32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000046 self.assertEqual(zlib.adler32(b"", 0), 0)
47 self.assertEqual(zlib.adler32(b"", 1), 1)
48 self.assertEqual(zlib.adler32(b"", 432), 432)
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000049
Guido van Rossum7d9ea502003-02-03 20:45:52 +000050 def test_penguins(self):
Martin Panterb82032f2015-12-11 05:19:29 +000051 self.assertEqual(zlib.crc32(b"penguin", 0), 0x0e5c1a120)
52 self.assertEqual(zlib.crc32(b"penguin", 1), 0x43b6aa94)
53 self.assertEqual(zlib.adler32(b"penguin", 0), 0x0bcf02f6)
54 self.assertEqual(zlib.adler32(b"penguin", 1), 0x0bd602f7)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000055
Guido van Rossum776152b2007-05-22 22:44:07 +000056 self.assertEqual(zlib.crc32(b"penguin"), zlib.crc32(b"penguin", 0))
57 self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000058
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000059 def test_crc32_adler32_unsigned(self):
Antoine Pitrou77b338b2009-12-14 18:00:06 +000060 foo = b'abcdefghijklmnop'
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000061 # explicitly test signed behavior
Gregory P. Smith27275032008-03-20 06:20:09 +000062 self.assertEqual(zlib.crc32(foo), 2486878355)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000063 self.assertEqual(zlib.crc32(b'spam'), 1138425661)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000064 self.assertEqual(zlib.adler32(foo+foo), 3573550353)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000065 self.assertEqual(zlib.adler32(b'spam'), 72286642)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000066
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000067 def test_same_as_binascii_crc32(self):
Martin v. Löwis15b16a32008-12-02 06:00:15 +000068 foo = b'abcdefghijklmnop'
Gregory P. Smith27275032008-03-20 06:20:09 +000069 crc = 2486878355
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000070 self.assertEqual(binascii.crc32(foo), crc)
71 self.assertEqual(zlib.crc32(foo), crc)
Martin v. Löwis15b16a32008-12-02 06:00:15 +000072 self.assertEqual(binascii.crc32(b'spam'), zlib.crc32(b'spam'))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000073
74
Victor Stinner8c663fd2017-11-08 14:44:44 -080075# Issue #10276 - check that inputs >=4 GiB are handled correctly.
Antoine Pitrouf3d22752011-02-21 18:09:00 +000076class ChecksumBigBufferTestCase(unittest.TestCase):
77
Nadeem Vawdabc8c8172012-02-23 14:16:15 +020078 @bigmemtest(size=_4G + 4, memuse=1, dry_run=False)
79 def test_big_buffer(self, size):
Nadeem Vawdab063a482012-02-23 13:36:25 +020080 data = b"nyan" * (_1G + 1)
81 self.assertEqual(zlib.crc32(data), 1044521549)
82 self.assertEqual(zlib.adler32(data), 2256789997)
Antoine Pitrouf3d22752011-02-21 18:09:00 +000083
Christian Heimesb186d002008-03-18 15:15:01 +000084
Guido van Rossum7d9ea502003-02-03 20:45:52 +000085class ExceptionTestCase(unittest.TestCase):
86 # make sure we generate some expected errors
Guido van Rossum8ce8a782007-11-01 19:42:39 +000087 def test_badlevel(self):
88 # specifying compression level out of range causes an error
89 # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib
90 # accepts 0 too)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000091 self.assertRaises(zlib.error, zlib.compress, b'ERROR', 10)
92
93 def test_badargs(self):
94 self.assertRaises(TypeError, zlib.adler32)
95 self.assertRaises(TypeError, zlib.crc32)
96 self.assertRaises(TypeError, zlib.compress)
97 self.assertRaises(TypeError, zlib.decompress)
98 for arg in (42, None, '', 'abc', (), []):
99 self.assertRaises(TypeError, zlib.adler32, arg)
100 self.assertRaises(TypeError, zlib.crc32, arg)
101 self.assertRaises(TypeError, zlib.compress, arg)
102 self.assertRaises(TypeError, zlib.decompress, arg)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000103
104 def test_badcompressobj(self):
105 # verify failure on building compress object with bad params
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000106 self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
Guido van Rossum8ce8a782007-11-01 19:42:39 +0000107 # specifying total bits too large causes an error
108 self.assertRaises(ValueError,
109 zlib.compressobj, 1, zlib.DEFLATED, zlib.MAX_WBITS + 1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000110
111 def test_baddecompressobj(self):
112 # verify failure on building decompress object with bad params
Antoine Pitrou90ee4df2010-04-06 17:23:13 +0000113 self.assertRaises(ValueError, zlib.decompressobj, -1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000114
Christian Heimes5e696852008-04-09 08:37:03 +0000115 def test_decompressobj_badflush(self):
116 # verify failure on calling decompressobj.flush with bad params
117 self.assertRaises(ValueError, zlib.decompressobj().flush, 0)
118 self.assertRaises(ValueError, zlib.decompressobj().flush, -1)
119
Martin Pantere99e9772015-11-20 08:13:35 +0000120 @support.cpython_only
121 def test_overflow(self):
122 with self.assertRaisesRegex(OverflowError, 'int too large'):
123 zlib.decompress(b'', 15, sys.maxsize + 1)
124 with self.assertRaisesRegex(OverflowError, 'int too large'):
Martin Panter84544c12016-07-23 03:02:07 +0000125 zlib.decompressobj().decompress(b'', sys.maxsize + 1)
126 with self.assertRaisesRegex(OverflowError, 'int too large'):
Martin Pantere99e9772015-11-20 08:13:35 +0000127 zlib.decompressobj().flush(sys.maxsize + 1)
128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000129
Antoine Pitrou89562712010-05-07 17:04:02 +0000130class BaseCompressTestCase(object):
131 def check_big_compress_buffer(self, size, compress_func):
132 _1M = 1024 * 1024
Victor Stinner8c663fd2017-11-08 14:44:44 -0800133 # Generate 10 MiB worth of random, and expand it by repeating it.
Antoine Pitrou89562712010-05-07 17:04:02 +0000134 # The assumption is that zlib's memory is not big enough to exploit
135 # such spread out redundancy.
136 data = b''.join([random.getrandbits(8 * _1M).to_bytes(_1M, 'little')
137 for i in range(10)])
138 data = data * (size // len(data) + 1)
139 try:
140 compress_func(data)
141 finally:
142 # Release memory
143 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000144
Antoine Pitrou89562712010-05-07 17:04:02 +0000145 def check_big_decompress_buffer(self, size, decompress_func):
146 data = b'x' * size
147 try:
148 compressed = zlib.compress(data, 1)
149 finally:
150 # Release memory
151 data = None
152 data = decompress_func(compressed)
153 # Sanity check
154 try:
155 self.assertEqual(len(data), size)
156 self.assertEqual(len(data.strip(b'x')), 0)
157 finally:
158 data = None
159
160
161class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000162 # Test compression in one go (whole message compression)
163 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000164 x = zlib.compress(HAMLET_SCENE)
165 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000166
Martin Panter1fe0d132016-02-10 10:06:36 +0000167 def test_keywords(self):
Serhiy Storchaka95657cd2016-06-25 22:43:05 +0300168 x = zlib.compress(HAMLET_SCENE, level=3)
Martin Panter1fe0d132016-02-10 10:06:36 +0000169 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Serhiy Storchaka95657cd2016-06-25 22:43:05 +0300170 with self.assertRaises(TypeError):
171 zlib.compress(data=HAMLET_SCENE, level=3)
Serhiy Storchaka15f32282016-08-15 10:06:16 +0300172 self.assertEqual(zlib.decompress(x,
173 wbits=zlib.MAX_WBITS,
174 bufsize=zlib.DEF_BUF_SIZE),
175 HAMLET_SCENE)
Martin Panter1fe0d132016-02-10 10:06:36 +0000176
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000177 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000178 # compress more data
179 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000180 x = zlib.compress(data)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000181 self.assertEqual(zlib.compress(bytearray(data)), x)
182 for ob in x, bytearray(x):
183 self.assertEqual(zlib.decompress(ob), data)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000184
Antoine Pitrou53b21662010-05-11 23:46:02 +0000185 def test_incomplete_stream(self):
Martin Panter6245cb32016-04-15 02:14:19 +0000186 # A useful error message is given
Antoine Pitrou53b21662010-05-11 23:46:02 +0000187 x = zlib.compress(HAMLET_SCENE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000188 self.assertRaisesRegex(zlib.error,
Antoine Pitrou53b21662010-05-11 23:46:02 +0000189 "Error -5 while decompressing data: incomplete or truncated stream",
190 zlib.decompress, x[:-1])
191
Antoine Pitrou89562712010-05-07 17:04:02 +0000192 # Memory use of the following functions takes into account overallocation
193
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200194 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000195 def test_big_compress_buffer(self, size):
196 compress = lambda s: zlib.compress(s, 1)
197 self.check_big_compress_buffer(size, compress)
198
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200199 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000200 def test_big_decompress_buffer(self, size):
201 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000202
Martin Pantere99e9772015-11-20 08:13:35 +0000203 @bigmemtest(size=_4G, memuse=1)
204 def test_large_bufsize(self, size):
205 # Test decompress(bufsize) parameter greater than the internal limit
206 data = HAMLET_SCENE * 10
207 compressed = zlib.compress(data, 1)
208 self.assertEqual(zlib.decompress(compressed, 15, size), data)
209
210 def test_custom_bufsize(self):
211 data = HAMLET_SCENE * 10
212 compressed = zlib.compress(data, 1)
213 self.assertEqual(zlib.decompress(compressed, 15, CustomInt()), data)
214
Martin Panter84544c12016-07-23 03:02:07 +0000215 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
216 @bigmemtest(size=_4G + 100, memuse=4)
217 def test_64bit_compress(self, size):
218 data = b'x' * size
219 try:
220 comp = zlib.compress(data, 0)
221 self.assertEqual(zlib.decompress(comp), data)
222 finally:
223 comp = data = None
224
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000225
Antoine Pitrou89562712010-05-07 17:04:02 +0000226class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000227 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000228 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000229 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000230 datasrc = HAMLET_SCENE * 128
231 datazip = zlib.compress(datasrc)
232 # should compress both bytes and bytearray data
233 for data in (datasrc, bytearray(datasrc)):
234 co = zlib.compressobj()
235 x1 = co.compress(data)
236 x2 = co.flush()
237 self.assertRaises(zlib.error, co.flush) # second flush should not work
238 self.assertEqual(x1 + x2, datazip)
239 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
240 dco = zlib.decompressobj()
241 y1 = dco.decompress(v1 + v2)
242 y2 = dco.flush()
243 self.assertEqual(data, y1 + y2)
244 self.assertIsInstance(dco.unconsumed_tail, bytes)
245 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000246
Serhiy Storchaka15f32282016-08-15 10:06:16 +0300247 def test_keywords(self):
248 level = 2
249 method = zlib.DEFLATED
250 wbits = -12
251 memLevel = 9
252 strategy = zlib.Z_FILTERED
253 co = zlib.compressobj(level=level,
254 method=method,
255 wbits=wbits,
256 memLevel=memLevel,
257 strategy=strategy,
258 zdict=b"")
259 do = zlib.decompressobj(wbits=wbits, zdict=b"")
260 with self.assertRaises(TypeError):
261 co.compress(data=HAMLET_SCENE)
262 with self.assertRaises(TypeError):
263 do.decompress(data=zlib.compress(HAMLET_SCENE))
264 x = co.compress(HAMLET_SCENE) + co.flush()
265 y = do.decompress(x, max_length=len(HAMLET_SCENE)) + do.flush()
266 self.assertEqual(HAMLET_SCENE, y)
267
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000268 def test_compressoptions(self):
269 # specify lots of options to compressobj()
270 level = 2
271 method = zlib.DEFLATED
272 wbits = -12
Martin Panterbf19d162015-09-09 01:01:13 +0000273 memLevel = 9
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000274 strategy = zlib.Z_FILTERED
Martin Panterbf19d162015-09-09 01:01:13 +0000275 co = zlib.compressobj(level, method, wbits, memLevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000276 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000277 x2 = co.flush()
278 dco = zlib.decompressobj(wbits)
279 y1 = dco.decompress(x1 + x2)
280 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000281 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000282
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000283 def test_compressincremental(self):
284 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000285 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000286 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000287 bufs = []
288 for i in range(0, len(data), 256):
289 bufs.append(co.compress(data[i:i+256]))
290 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000291 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000292
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000293 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000294 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000295 y2 = dco.flush()
296 self.assertEqual(data, y1 + y2)
297
Neil Schemenauer6412b122004-06-05 19:34:28 +0000298 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000299 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000300 source = source or HAMLET_SCENE
301 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000302 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000303 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000304 for i in range(0, len(data), cx):
305 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000306 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000307 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000308
Gregory P. Smith693fc462008-09-06 20:13:06 +0000309 decombuf = zlib.decompress(combuf)
310 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000311 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000312
313 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000314
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000315 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000316 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000317 for i in range(0, len(combuf), dcx):
318 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000319 self.assertEqual(b'', dco.unconsumed_tail, ########
320 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000321 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000322 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000323 if flush:
324 bufs.append(dco.flush())
325 else:
326 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000327 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000328 if chunk:
329 bufs.append(chunk)
330 else:
331 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000332 self.assertEqual(b'', dco.unconsumed_tail, ########
333 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000334 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000335 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000336 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000337 # Failure means: "decompressobj with init options failed"
338
Neil Schemenauer6412b122004-06-05 19:34:28 +0000339 def test_decompincflush(self):
340 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000341
Neil Schemenauer6412b122004-06-05 19:34:28 +0000342 def test_decompimax(self, source=None, cx=256, dcx=64):
343 # compress in steps, decompress in length-restricted steps
344 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000345 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000346 data = source * 128
347 co = zlib.compressobj()
348 bufs = []
349 for i in range(0, len(data), cx):
350 bufs.append(co.compress(data[i:i+cx]))
351 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000352 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000353 self.assertEqual(data, zlib.decompress(combuf),
354 'compressed data failure')
355
356 dco = zlib.decompressobj()
357 bufs = []
358 cb = combuf
359 while cb:
360 #max_length = 1 + len(cb)//10
361 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000362 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000363 'chunk too big (%d>%d)' % (len(chunk), dcx))
364 bufs.append(chunk)
365 cb = dco.unconsumed_tail
366 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000367 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000368
369 def test_decompressmaxlen(self, flush=False):
370 # Check a decompression object with max_length specified
371 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000372 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000373 bufs = []
374 for i in range(0, len(data), 256):
375 bufs.append(co.compress(data[i:i+256]))
376 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000377 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000378 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000379 'compressed data failure')
380
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000381 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000382 bufs = []
383 cb = combuf
384 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000385 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000386 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000387 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000388 'chunk too big (%d>%d)' % (len(chunk),max_length))
389 bufs.append(chunk)
390 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000391 if flush:
392 bufs.append(dco.flush())
393 else:
394 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000395 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000396 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000397 'chunk too big (%d>%d)' % (len(chunk),max_length))
398 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000399 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000400
Neil Schemenauer6412b122004-06-05 19:34:28 +0000401 def test_decompressmaxlenflush(self):
402 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000403
404 def test_maxlenmisc(self):
405 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000406 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000407 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000408 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000409
Martin Pantere99e9772015-11-20 08:13:35 +0000410 def test_maxlen_large(self):
411 # Sizes up to sys.maxsize should be accepted, although zlib is
412 # internally limited to expressing sizes with unsigned int
413 data = HAMLET_SCENE * 10
414 self.assertGreater(len(data), zlib.DEF_BUF_SIZE)
415 compressed = zlib.compress(data, 1)
416 dco = zlib.decompressobj()
417 self.assertEqual(dco.decompress(compressed, sys.maxsize), data)
418
419 def test_maxlen_custom(self):
420 data = HAMLET_SCENE * 10
421 compressed = zlib.compress(data, 1)
422 dco = zlib.decompressobj()
423 self.assertEqual(dco.decompress(compressed, CustomInt()), data[:100])
424
Nadeem Vawda7619e882011-05-14 14:05:20 +0200425 def test_clear_unconsumed_tail(self):
426 # Issue #12050: calling decompress() without providing max_length
427 # should clear the unconsumed_tail attribute.
428 cdata = b"x\x9cKLJ\x06\x00\x02M\x01" # "abc"
429 dco = zlib.decompressobj()
430 ddata = dco.decompress(cdata, 1)
431 ddata += dco.decompress(dco.unconsumed_tail)
432 self.assertEqual(dco.unconsumed_tail, b"")
433
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000434 def test_flushes(self):
435 # Test flush() with the various options, using all the
436 # different levels in order to provide more variations.
437 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
438 sync_opt = [getattr(zlib, opt) for opt in sync_opt
439 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000440 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000441
442 for sync in sync_opt:
443 for level in range(10):
444 obj = zlib.compressobj( level )
445 a = obj.compress( data[:3000] )
446 b = obj.flush( sync )
447 c = obj.compress( data[3000:] )
448 d = obj.flush()
Guido van Rossum776152b2007-05-22 22:44:07 +0000449 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000450 data, ("Decompress failed: flush "
451 "mode=%i, level=%i") % (sync, level))
452 del obj
453
Serhiy Storchaka43767632013-11-03 21:31:38 +0200454 @unittest.skipUnless(hasattr(zlib, 'Z_SYNC_FLUSH'),
455 'requires zlib.Z_SYNC_FLUSH')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000456 def test_odd_flush(self):
457 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
458 import random
Serhiy Storchaka43767632013-11-03 21:31:38 +0200459 # Testing on 17K of "random" data
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000460
Serhiy Storchaka43767632013-11-03 21:31:38 +0200461 # Create compressor and decompressor objects
462 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
463 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000464
Serhiy Storchaka43767632013-11-03 21:31:38 +0200465 # Try 17K of data
466 # generate random data stream
467 try:
468 # In 2.3 and later, WichmannHill is the RNG of the bug report
469 gen = random.WichmannHill()
470 except AttributeError:
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000471 try:
Serhiy Storchaka43767632013-11-03 21:31:38 +0200472 # 2.2 called it Random
473 gen = random.Random()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000474 except AttributeError:
Serhiy Storchaka43767632013-11-03 21:31:38 +0200475 # others might simply have a single RNG
476 gen = random
477 gen.seed(1)
478 data = genblock(1, 17 * 1024, generator=gen)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000479
Serhiy Storchaka43767632013-11-03 21:31:38 +0200480 # compress, sync-flush, and decompress
481 first = co.compress(data)
482 second = co.flush(zlib.Z_SYNC_FLUSH)
483 expanded = dco.decompress(first + second)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000484
Serhiy Storchaka43767632013-11-03 21:31:38 +0200485 # if decompressed data is different from the input data, choke.
486 self.assertEqual(expanded, data, "17K random source doesn't match")
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000487
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000488 def test_empty_flush(self):
489 # Test that calling .flush() on unused objects works.
490 # (Bug #1083110 -- calling .flush() on decompress objects
491 # caused a core dump.)
492
493 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000494 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000495 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000496 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000497
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200498 def test_dictionary(self):
499 h = HAMLET_SCENE
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200500 # Build a simulated dictionary out of the words in HAMLET.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200501 words = h.split()
502 random.shuffle(words)
503 zdict = b''.join(words)
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200504 # Use it to compress HAMLET.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200505 co = zlib.compressobj(zdict=zdict)
506 cd = co.compress(h) + co.flush()
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200507 # Verify that it will decompress with the dictionary.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200508 dco = zlib.decompressobj(zdict=zdict)
509 self.assertEqual(dco.decompress(cd) + dco.flush(), h)
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200510 # Verify that it fails when not given the dictionary.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200511 dco = zlib.decompressobj()
512 self.assertRaises(zlib.error, dco.decompress, cd)
513
514 def test_dictionary_streaming(self):
Nadeem Vawdacf5e1d82012-06-22 00:35:57 +0200515 # This simulates the reuse of a compressor object for compressing
516 # several separate data streams.
Nadeem Vawdafd8a8382012-06-21 02:13:12 +0200517 co = zlib.compressobj(zdict=HAMLET_SCENE)
518 do = zlib.decompressobj(zdict=HAMLET_SCENE)
519 piece = HAMLET_SCENE[1000:1500]
520 d0 = co.compress(piece) + co.flush(zlib.Z_SYNC_FLUSH)
521 d1 = co.compress(piece[100:]) + co.flush(zlib.Z_SYNC_FLUSH)
522 d2 = co.compress(piece[:-100]) + co.flush(zlib.Z_SYNC_FLUSH)
523 self.assertEqual(do.decompress(d0), piece)
524 self.assertEqual(do.decompress(d1), piece[100:])
525 self.assertEqual(do.decompress(d2), piece[:-100])
526
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000527 def test_decompress_incomplete_stream(self):
528 # This is 'foo', deflated
529 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
530 # For the record
531 self.assertEqual(zlib.decompress(x), b'foo')
532 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
533 # Omitting the stream end works with decompressor objects
534 # (see issue #8672).
535 dco = zlib.decompressobj()
536 y = dco.decompress(x[:-5])
537 y += dco.flush()
538 self.assertEqual(y, b'foo')
539
Nadeem Vawda1c385462011-08-13 15:22:40 +0200540 def test_decompress_eof(self):
541 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
542 dco = zlib.decompressobj()
543 self.assertFalse(dco.eof)
544 dco.decompress(x[:-5])
545 self.assertFalse(dco.eof)
546 dco.decompress(x[-5:])
547 self.assertTrue(dco.eof)
548 dco.flush()
549 self.assertTrue(dco.eof)
550
551 def test_decompress_eof_incomplete_stream(self):
552 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E' # 'foo'
553 dco = zlib.decompressobj()
554 self.assertFalse(dco.eof)
555 dco.decompress(x[:-5])
556 self.assertFalse(dco.eof)
557 dco.flush()
558 self.assertFalse(dco.eof)
559
Nadeem Vawda39079942012-11-05 00:37:42 +0100560 def test_decompress_unused_data(self):
561 # Repeated calls to decompress() after EOF should accumulate data in
562 # dco.unused_data, instead of just storing the arg to the last call.
Nadeem Vawdaee7889d2012-11-11 02:14:36 +0100563 source = b'abcdefghijklmnopqrstuvwxyz'
564 remainder = b'0123456789'
565 y = zlib.compress(source)
566 x = y + remainder
567 for maxlen in 0, 1000:
568 for step in 1, 2, len(y), len(x):
569 dco = zlib.decompressobj()
570 data = b''
571 for i in range(0, len(x), step):
572 if i < len(y):
573 self.assertEqual(dco.unused_data, b'')
574 if maxlen == 0:
575 data += dco.decompress(x[i : i + step])
576 self.assertEqual(dco.unconsumed_tail, b'')
577 else:
578 data += dco.decompress(
579 dco.unconsumed_tail + x[i : i + step], maxlen)
580 data += dco.flush()
Nadeem Vawdadd1253a2012-11-11 02:21:22 +0100581 self.assertTrue(dco.eof)
Nadeem Vawdaee7889d2012-11-11 02:14:36 +0100582 self.assertEqual(data, source)
583 self.assertEqual(dco.unconsumed_tail, b'')
584 self.assertEqual(dco.unused_data, remainder)
Nadeem Vawda39079942012-11-05 00:37:42 +0100585
Martin Panter3f0ee832016-06-05 10:48:34 +0000586 # issue27164
587 def test_decompress_raw_with_dictionary(self):
588 zdict = b'abcdefghijklmnopqrstuvwxyz'
589 co = zlib.compressobj(wbits=-zlib.MAX_WBITS, zdict=zdict)
590 comp = co.compress(zdict) + co.flush()
591 dco = zlib.decompressobj(wbits=-zlib.MAX_WBITS, zdict=zdict)
592 uncomp = dco.decompress(comp) + dco.flush()
593 self.assertEqual(zdict, uncomp)
594
Nadeem Vawda7ee95552012-11-11 03:15:32 +0100595 def test_flush_with_freed_input(self):
596 # Issue #16411: decompressor accesses input to last decompress() call
597 # in flush(), even if this object has been freed in the meanwhile.
598 input1 = b'abcdefghijklmnopqrstuvwxyz'
599 input2 = b'QWERTYUIOPASDFGHJKLZXCVBNM'
600 data = zlib.compress(input1)
601 dco = zlib.decompressobj()
602 dco.decompress(data, 1)
603 del data
604 data = zlib.compress(input2)
605 self.assertEqual(dco.flush(), input1[1:])
606
Martin Pantere99e9772015-11-20 08:13:35 +0000607 @bigmemtest(size=_4G, memuse=1)
608 def test_flush_large_length(self, size):
609 # Test flush(length) parameter greater than internal limit UINT_MAX
610 input = HAMLET_SCENE * 10
611 data = zlib.compress(input, 1)
612 dco = zlib.decompressobj()
613 dco.decompress(data, 1)
614 self.assertEqual(dco.flush(size), input[1:])
615
616 def test_flush_custom_length(self):
617 input = HAMLET_SCENE * 10
618 data = zlib.compress(input, 1)
619 dco = zlib.decompressobj()
620 dco.decompress(data, 1)
621 self.assertEqual(dco.flush(CustomInt()), input[1:])
622
Serhiy Storchaka43767632013-11-03 21:31:38 +0200623 @requires_Compress_copy
624 def test_compresscopy(self):
625 # Test copying a compression object
626 data0 = HAMLET_SCENE
627 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
628 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
629 bufs0 = []
630 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000631
Serhiy Storchaka43767632013-11-03 21:31:38 +0200632 c1 = c0.copy()
633 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000634
Serhiy Storchaka43767632013-11-03 21:31:38 +0200635 bufs0.append(c0.compress(data0))
636 bufs0.append(c0.flush())
637 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000638
Serhiy Storchaka43767632013-11-03 21:31:38 +0200639 bufs1.append(c1.compress(data1))
640 bufs1.append(c1.flush())
641 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000642
Serhiy Storchaka43767632013-11-03 21:31:38 +0200643 self.assertEqual(zlib.decompress(s0),data0+data0)
644 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000645
Serhiy Storchaka43767632013-11-03 21:31:38 +0200646 @requires_Compress_copy
647 def test_badcompresscopy(self):
648 # Test copying a compression object in an inconsistent state
649 c = zlib.compressobj()
650 c.compress(HAMLET_SCENE)
651 c.flush()
652 self.assertRaises(ValueError, c.copy)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000653
Serhiy Storchaka43767632013-11-03 21:31:38 +0200654 @requires_Decompress_copy
655 def test_decompresscopy(self):
656 # Test copying a decompression object
657 data = HAMLET_SCENE
658 comp = zlib.compress(data)
659 # Test type of return value
660 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000661
Serhiy Storchaka43767632013-11-03 21:31:38 +0200662 d0 = zlib.decompressobj()
663 bufs0 = []
664 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000665
Serhiy Storchaka43767632013-11-03 21:31:38 +0200666 d1 = d0.copy()
667 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000668
Serhiy Storchaka43767632013-11-03 21:31:38 +0200669 bufs0.append(d0.decompress(comp[32:]))
670 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000671
Serhiy Storchaka43767632013-11-03 21:31:38 +0200672 bufs1.append(d1.decompress(comp[32:]))
673 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000674
Serhiy Storchaka43767632013-11-03 21:31:38 +0200675 self.assertEqual(s0,s1)
676 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000677
Serhiy Storchaka43767632013-11-03 21:31:38 +0200678 @requires_Decompress_copy
679 def test_baddecompresscopy(self):
680 # Test copying a compression object in an inconsistent state
681 data = zlib.compress(HAMLET_SCENE)
682 d = zlib.decompressobj()
683 d.decompress(data)
684 d.flush()
685 self.assertRaises(ValueError, d.copy)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000686
Serhiy Storchakad7a44152015-11-12 11:23:04 +0200687 def test_compresspickle(self):
688 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
689 with self.assertRaises((TypeError, pickle.PicklingError)):
690 pickle.dumps(zlib.compressobj(zlib.Z_BEST_COMPRESSION), proto)
691
692 def test_decompresspickle(self):
693 for proto in range(pickle.HIGHEST_PROTOCOL + 1):
694 with self.assertRaises((TypeError, pickle.PicklingError)):
695 pickle.dumps(zlib.decompressobj(), proto)
696
Antoine Pitrou89562712010-05-07 17:04:02 +0000697 # Memory use of the following functions takes into account overallocation
698
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200699 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000700 def test_big_compress_buffer(self, size):
701 c = zlib.compressobj(1)
702 compress = lambda s: c.compress(s) + c.flush()
703 self.check_big_compress_buffer(size, compress)
704
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200705 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000706 def test_big_decompress_buffer(self, size):
707 d = zlib.decompressobj()
708 decompress = lambda s: d.decompress(s) + d.flush()
709 self.check_big_decompress_buffer(size, decompress)
710
Martin Panter84544c12016-07-23 03:02:07 +0000711 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
712 @bigmemtest(size=_4G + 100, memuse=4)
713 def test_64bit_compress(self, size):
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200714 data = b'x' * size
Martin Panter84544c12016-07-23 03:02:07 +0000715 co = zlib.compressobj(0)
716 do = zlib.decompressobj()
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200717 try:
Martin Panter84544c12016-07-23 03:02:07 +0000718 comp = co.compress(data) + co.flush()
719 uncomp = do.decompress(comp) + do.flush()
720 self.assertEqual(uncomp, data)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200721 finally:
Martin Panter84544c12016-07-23 03:02:07 +0000722 comp = uncomp = data = None
723
724 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
725 @bigmemtest(size=_4G + 100, memuse=3)
726 def test_large_unused_data(self, size):
727 data = b'abcdefghijklmnop'
728 unused = b'x' * size
729 comp = zlib.compress(data) + unused
730 do = zlib.decompressobj()
731 try:
732 uncomp = do.decompress(comp) + do.flush()
733 self.assertEqual(unused, do.unused_data)
734 self.assertEqual(uncomp, data)
735 finally:
736 unused = comp = do = None
737
738 @unittest.skipUnless(sys.maxsize > 2**32, 'requires 64bit platform')
739 @bigmemtest(size=_4G + 100, memuse=5)
740 def test_large_unconsumed_tail(self, size):
741 data = b'x' * size
742 do = zlib.decompressobj()
743 try:
744 comp = zlib.compress(data, 0)
745 uncomp = do.decompress(comp, 1) + do.flush()
746 self.assertEqual(uncomp, data)
747 self.assertEqual(do.unconsumed_tail, b'')
748 finally:
749 comp = uncomp = data = None
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200750
Martin Panter0fdf41d2016-05-27 07:32:11 +0000751 def test_wbits(self):
Martin Panterc618ae82016-05-27 11:20:21 +0000752 # wbits=0 only supported since zlib v1.2.3.5
753 # Register "1.2.3" as "1.2.3.0"
754 v = (zlib.ZLIB_RUNTIME_VERSION + ".0").split(".", 4)
755 supports_wbits_0 = int(v[0]) > 1 or int(v[0]) == 1 \
756 and (int(v[1]) > 2 or int(v[1]) == 2
757 and (int(v[2]) > 3 or int(v[2]) == 3 and int(v[3]) >= 5))
758
Martin Panter0fdf41d2016-05-27 07:32:11 +0000759 co = zlib.compressobj(level=1, wbits=15)
760 zlib15 = co.compress(HAMLET_SCENE) + co.flush()
761 self.assertEqual(zlib.decompress(zlib15, 15), HAMLET_SCENE)
Martin Panterc618ae82016-05-27 11:20:21 +0000762 if supports_wbits_0:
763 self.assertEqual(zlib.decompress(zlib15, 0), HAMLET_SCENE)
Martin Panter0fdf41d2016-05-27 07:32:11 +0000764 self.assertEqual(zlib.decompress(zlib15, 32 + 15), HAMLET_SCENE)
765 with self.assertRaisesRegex(zlib.error, 'invalid window size'):
766 zlib.decompress(zlib15, 14)
767 dco = zlib.decompressobj(wbits=32 + 15)
768 self.assertEqual(dco.decompress(zlib15), HAMLET_SCENE)
769 dco = zlib.decompressobj(wbits=14)
770 with self.assertRaisesRegex(zlib.error, 'invalid window size'):
771 dco.decompress(zlib15)
772
773 co = zlib.compressobj(level=1, wbits=9)
774 zlib9 = co.compress(HAMLET_SCENE) + co.flush()
775 self.assertEqual(zlib.decompress(zlib9, 9), HAMLET_SCENE)
776 self.assertEqual(zlib.decompress(zlib9, 15), HAMLET_SCENE)
Martin Panterc618ae82016-05-27 11:20:21 +0000777 if supports_wbits_0:
778 self.assertEqual(zlib.decompress(zlib9, 0), HAMLET_SCENE)
Martin Panter0fdf41d2016-05-27 07:32:11 +0000779 self.assertEqual(zlib.decompress(zlib9, 32 + 9), HAMLET_SCENE)
780 dco = zlib.decompressobj(wbits=32 + 9)
781 self.assertEqual(dco.decompress(zlib9), HAMLET_SCENE)
782
783 co = zlib.compressobj(level=1, wbits=-15)
784 deflate15 = co.compress(HAMLET_SCENE) + co.flush()
785 self.assertEqual(zlib.decompress(deflate15, -15), HAMLET_SCENE)
786 dco = zlib.decompressobj(wbits=-15)
787 self.assertEqual(dco.decompress(deflate15), HAMLET_SCENE)
788
789 co = zlib.compressobj(level=1, wbits=-9)
790 deflate9 = co.compress(HAMLET_SCENE) + co.flush()
791 self.assertEqual(zlib.decompress(deflate9, -9), HAMLET_SCENE)
792 self.assertEqual(zlib.decompress(deflate9, -15), HAMLET_SCENE)
793 dco = zlib.decompressobj(wbits=-9)
794 self.assertEqual(dco.decompress(deflate9), HAMLET_SCENE)
795
796 co = zlib.compressobj(level=1, wbits=16 + 15)
797 gzip = co.compress(HAMLET_SCENE) + co.flush()
798 self.assertEqual(zlib.decompress(gzip, 16 + 15), HAMLET_SCENE)
799 self.assertEqual(zlib.decompress(gzip, 32 + 15), HAMLET_SCENE)
800 dco = zlib.decompressobj(32 + 15)
801 self.assertEqual(dco.decompress(gzip), HAMLET_SCENE)
802
Antoine Pitrou89562712010-05-07 17:04:02 +0000803
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000804def genblock(seed, length, step=1024, generator=random):
805 """length-byte stream of random data from a seed (in step-byte blocks)."""
806 if seed is not None:
807 generator.seed(seed)
808 randint = generator.randint
809 if length < step or step < 2:
810 step = length
Guido van Rossum776152b2007-05-22 22:44:07 +0000811 blocks = bytes()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000812 for i in range(0, length, step):
Guido van Rossum776152b2007-05-22 22:44:07 +0000813 blocks += bytes(randint(0, 255) for x in range(step))
814 return blocks
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000815
816
817
818def choose_lines(source, number, seed=None, generator=random):
819 """Return a list of number lines randomly chosen from the source"""
820 if seed is not None:
821 generator.seed(seed)
822 sources = source.split('\n')
823 return [generator.choice(sources) for n in range(number)]
824
825
826
Guido van Rossum776152b2007-05-22 22:44:07 +0000827HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000828LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000829
830 O, fear me not.
831 I stay too long: but here my father comes.
832
833 Enter POLONIUS
834
835 A double blessing is a double grace,
836 Occasion smiles upon a second leave.
837
Fred Drake004d5e62000-10-23 17:22:08 +0000838LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000839
840 Yet here, Laertes! aboard, aboard, for shame!
841 The wind sits in the shoulder of your sail,
842 And you are stay'd for. There; my blessing with thee!
843 And these few precepts in thy memory
844 See thou character. Give thy thoughts no tongue,
845 Nor any unproportioned thought his act.
846 Be thou familiar, but by no means vulgar.
847 Those friends thou hast, and their adoption tried,
848 Grapple them to thy soul with hoops of steel;
849 But do not dull thy palm with entertainment
850 Of each new-hatch'd, unfledged comrade. Beware
851 Of entrance to a quarrel, but being in,
852 Bear't that the opposed may beware of thee.
853 Give every man thy ear, but few thy voice;
854 Take each man's censure, but reserve thy judgment.
855 Costly thy habit as thy purse can buy,
856 But not express'd in fancy; rich, not gaudy;
857 For the apparel oft proclaims the man,
858 And they in France of the best rank and station
859 Are of a most select and generous chief in that.
860 Neither a borrower nor a lender be;
861 For loan oft loses both itself and friend,
862 And borrowing dulls the edge of husbandry.
863 This above all: to thine ownself be true,
864 And it must follow, as the night the day,
865 Thou canst not then be false to any man.
866 Farewell: my blessing season this in thee!
867
Fred Drake004d5e62000-10-23 17:22:08 +0000868LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000869
870 Most humbly do I take my leave, my lord.
871
Fred Drake004d5e62000-10-23 17:22:08 +0000872LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000873
874 The time invites you; go; your servants tend.
875
Fred Drake004d5e62000-10-23 17:22:08 +0000876LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000877
878 Farewell, Ophelia; and remember well
879 What I have said to you.
880
Fred Drake004d5e62000-10-23 17:22:08 +0000881OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000882
883 'Tis in my memory lock'd,
884 And you yourself shall keep the key of it.
885
Fred Drake004d5e62000-10-23 17:22:08 +0000886LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000887
888 Farewell.
889"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000890
891
Martin Pantere99e9772015-11-20 08:13:35 +0000892class CustomInt:
893 def __int__(self):
894 return 100
895
896
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000897if __name__ == "__main__":
Zachary Ware38c707e2015-04-13 15:00:43 -0500898 unittest.main()