blob: 4661c1d6135662f262700c2209d9e0003bcc6f38 [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
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00004import random
Antoine Pitrouf3d22752011-02-21 18:09:00 +00005import sys
Antoine Pitrou94190bb2011-10-04 10:22:36 +02006from test.support import bigmemtest, _1G, _4G
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +00007
R. David Murraya21e4ca2009-03-31 23:16:50 +00008zlib = support.import_module('zlib')
9
Antoine Pitrouf3d22752011-02-21 18:09:00 +000010try:
11 import mmap
12except ImportError:
13 mmap = None
14
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000015
Guido van Rossum7d9ea502003-02-03 20:45:52 +000016class ChecksumTestCase(unittest.TestCase):
17 # checksum test cases
18 def test_crc32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000019 self.assertEqual(zlib.crc32(b""), zlib.crc32(b"", 0))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000020 self.assertTrue(zlib.crc32(b"abc", 0xffffffff))
Andrew M. Kuchlingfcfc8d52001-08-10 15:50:11 +000021
Guido van Rossum7d9ea502003-02-03 20:45:52 +000022 def test_crc32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000023 self.assertEqual(zlib.crc32(b"", 0), 0)
24 self.assertEqual(zlib.crc32(b"", 1), 1)
25 self.assertEqual(zlib.crc32(b"", 432), 432)
Andrew M. Kuchling9a0f98e2001-02-21 02:17:01 +000026
Guido van Rossum7d9ea502003-02-03 20:45:52 +000027 def test_adler32start(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000028 self.assertEqual(zlib.adler32(b""), zlib.adler32(b"", 1))
Benjamin Petersonc9c0f202009-06-30 23:06:06 +000029 self.assertTrue(zlib.adler32(b"abc", 0xffffffff))
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000030
Guido van Rossum7d9ea502003-02-03 20:45:52 +000031 def test_adler32empty(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000032 self.assertEqual(zlib.adler32(b"", 0), 0)
33 self.assertEqual(zlib.adler32(b"", 1), 1)
34 self.assertEqual(zlib.adler32(b"", 432), 432)
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +000035
Guido van Rossum7d9ea502003-02-03 20:45:52 +000036 def assertEqual32(self, seen, expected):
37 # 32-bit values masked -- checksums on 32- vs 64- bit machines
38 # This is important if bit 31 (0x08000000L) is set.
Guido van Rossume2a383d2007-01-15 16:59:06 +000039 self.assertEqual(seen & 0x0FFFFFFFF, expected & 0x0FFFFFFFF)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000040
41 def test_penguins(self):
Guido van Rossum776152b2007-05-22 22:44:07 +000042 self.assertEqual32(zlib.crc32(b"penguin", 0), 0x0e5c1a120)
43 self.assertEqual32(zlib.crc32(b"penguin", 1), 0x43b6aa94)
44 self.assertEqual32(zlib.adler32(b"penguin", 0), 0x0bcf02f6)
45 self.assertEqual32(zlib.adler32(b"penguin", 1), 0x0bd602f7)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000046
Guido van Rossum776152b2007-05-22 22:44:07 +000047 self.assertEqual(zlib.crc32(b"penguin"), zlib.crc32(b"penguin", 0))
48 self.assertEqual(zlib.adler32(b"penguin"),zlib.adler32(b"penguin",1))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000049
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000050 def test_crc32_adler32_unsigned(self):
Antoine Pitrou77b338b2009-12-14 18:00:06 +000051 foo = b'abcdefghijklmnop'
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000052 # explicitly test signed behavior
Gregory P. Smith27275032008-03-20 06:20:09 +000053 self.assertEqual(zlib.crc32(foo), 2486878355)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000054 self.assertEqual(zlib.crc32(b'spam'), 1138425661)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000055 self.assertEqual(zlib.adler32(foo+foo), 3573550353)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000056 self.assertEqual(zlib.adler32(b'spam'), 72286642)
Gregory P. Smithab0d8a12008-03-17 20:24:09 +000057
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000058 def test_same_as_binascii_crc32(self):
Martin v. Löwis15b16a32008-12-02 06:00:15 +000059 foo = b'abcdefghijklmnop'
Gregory P. Smith27275032008-03-20 06:20:09 +000060 crc = 2486878355
Christian Heimesd5e2b6f2008-03-19 21:50:51 +000061 self.assertEqual(binascii.crc32(foo), crc)
62 self.assertEqual(zlib.crc32(foo), crc)
Martin v. Löwis15b16a32008-12-02 06:00:15 +000063 self.assertEqual(binascii.crc32(b'spam'), zlib.crc32(b'spam'))
Guido van Rossum7d9ea502003-02-03 20:45:52 +000064
65
Antoine Pitrouf3d22752011-02-21 18:09:00 +000066# Issue #10276 - check that inputs >=4GB are handled correctly.
67class ChecksumBigBufferTestCase(unittest.TestCase):
68
Nadeem Vawda05a4dd82012-02-27 00:42:58 +020069 @bigmemtest(size=_4G + 4, memuse=1, dry_run=False)
70 def test_big_buffer(self, size):
71 data = b"nyan" * (_1G + 1)
72 self.assertEqual(zlib.crc32(data), 1044521549)
73 self.assertEqual(zlib.adler32(data), 2256789997)
Antoine Pitrouf3d22752011-02-21 18:09:00 +000074
Christian Heimesb186d002008-03-18 15:15:01 +000075
Guido van Rossum7d9ea502003-02-03 20:45:52 +000076class ExceptionTestCase(unittest.TestCase):
77 # make sure we generate some expected errors
Guido van Rossum8ce8a782007-11-01 19:42:39 +000078 def test_badlevel(self):
79 # specifying compression level out of range causes an error
80 # (but -1 is Z_DEFAULT_COMPRESSION and apparently the zlib
81 # accepts 0 too)
Antoine Pitrou77b338b2009-12-14 18:00:06 +000082 self.assertRaises(zlib.error, zlib.compress, b'ERROR', 10)
83
84 def test_badargs(self):
85 self.assertRaises(TypeError, zlib.adler32)
86 self.assertRaises(TypeError, zlib.crc32)
87 self.assertRaises(TypeError, zlib.compress)
88 self.assertRaises(TypeError, zlib.decompress)
89 for arg in (42, None, '', 'abc', (), []):
90 self.assertRaises(TypeError, zlib.adler32, arg)
91 self.assertRaises(TypeError, zlib.crc32, arg)
92 self.assertRaises(TypeError, zlib.compress, arg)
93 self.assertRaises(TypeError, zlib.decompress, arg)
Guido van Rossum7d9ea502003-02-03 20:45:52 +000094
95 def test_badcompressobj(self):
96 # verify failure on building compress object with bad params
Neil Schemenauer94afd3e2004-06-05 19:02:52 +000097 self.assertRaises(ValueError, zlib.compressobj, 1, zlib.DEFLATED, 0)
Guido van Rossum8ce8a782007-11-01 19:42:39 +000098 # specifying total bits too large causes an error
99 self.assertRaises(ValueError,
100 zlib.compressobj, 1, zlib.DEFLATED, zlib.MAX_WBITS + 1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000101
102 def test_baddecompressobj(self):
103 # verify failure on building decompress object with bad params
Antoine Pitrou90ee4df2010-04-06 17:23:13 +0000104 self.assertRaises(ValueError, zlib.decompressobj, -1)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000105
Christian Heimes5e696852008-04-09 08:37:03 +0000106 def test_decompressobj_badflush(self):
107 # verify failure on calling decompressobj.flush with bad params
108 self.assertRaises(ValueError, zlib.decompressobj().flush, 0)
109 self.assertRaises(ValueError, zlib.decompressobj().flush, -1)
110
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000111
Antoine Pitrou89562712010-05-07 17:04:02 +0000112class BaseCompressTestCase(object):
113 def check_big_compress_buffer(self, size, compress_func):
114 _1M = 1024 * 1024
115 fmt = "%%0%dx" % (2 * _1M)
116 # Generate 10MB worth of random, and expand it by repeating it.
117 # The assumption is that zlib's memory is not big enough to exploit
118 # such spread out redundancy.
119 data = b''.join([random.getrandbits(8 * _1M).to_bytes(_1M, 'little')
120 for i in range(10)])
121 data = data * (size // len(data) + 1)
122 try:
123 compress_func(data)
124 finally:
125 # Release memory
126 data = None
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000127
Antoine Pitrou89562712010-05-07 17:04:02 +0000128 def check_big_decompress_buffer(self, size, decompress_func):
129 data = b'x' * size
130 try:
131 compressed = zlib.compress(data, 1)
132 finally:
133 # Release memory
134 data = None
135 data = decompress_func(compressed)
136 # Sanity check
137 try:
138 self.assertEqual(len(data), size)
139 self.assertEqual(len(data.strip(b'x')), 0)
140 finally:
141 data = None
142
143
144class CompressTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000145 # Test compression in one go (whole message compression)
146 def test_speech(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000147 x = zlib.compress(HAMLET_SCENE)
148 self.assertEqual(zlib.decompress(x), HAMLET_SCENE)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000149
150 def test_speech128(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000151 # compress more data
152 data = HAMLET_SCENE * 128
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000153 x = zlib.compress(data)
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000154 self.assertEqual(zlib.compress(bytearray(data)), x)
155 for ob in x, bytearray(x):
156 self.assertEqual(zlib.decompress(ob), data)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000157
Antoine Pitrou53b21662010-05-11 23:46:02 +0000158 def test_incomplete_stream(self):
159 # An useful error message is given
160 x = zlib.compress(HAMLET_SCENE)
Ezio Melottied3a7d22010-12-01 02:32:32 +0000161 self.assertRaisesRegex(zlib.error,
Antoine Pitrou53b21662010-05-11 23:46:02 +0000162 "Error -5 while decompressing data: incomplete or truncated stream",
163 zlib.decompress, x[:-1])
164
Antoine Pitrou89562712010-05-07 17:04:02 +0000165 # Memory use of the following functions takes into account overallocation
166
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200167 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000168 def test_big_compress_buffer(self, size):
169 compress = lambda s: zlib.compress(s, 1)
170 self.check_big_compress_buffer(size, compress)
171
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200172 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000173 def test_big_decompress_buffer(self, size):
174 self.check_big_decompress_buffer(size, zlib.decompress)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000175
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200176 @bigmemtest(size=_4G + 100, memuse=1)
Victor Stinner8848c7a2011-01-04 02:07:36 +0000177 def test_length_overflow(self, size):
178 if size < _4G + 100:
179 self.skipTest("not enough free memory, need at least 4 GB")
180 data = b'x' * size
181 try:
182 self.assertRaises(OverflowError, zlib.compress, data, 1)
Nadeem Vawda154bdf92011-05-14 23:07:36 +0200183 self.assertRaises(OverflowError, zlib.decompress, data)
Victor Stinner8848c7a2011-01-04 02:07:36 +0000184 finally:
185 data = None
186
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000187
Antoine Pitrou89562712010-05-07 17:04:02 +0000188class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000189 # Test compression object
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000190 def test_pair(self):
Neil Schemenauer6412b122004-06-05 19:34:28 +0000191 # straightforward compress/decompress objects
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000192 datasrc = HAMLET_SCENE * 128
193 datazip = zlib.compress(datasrc)
194 # should compress both bytes and bytearray data
195 for data in (datasrc, bytearray(datasrc)):
196 co = zlib.compressobj()
197 x1 = co.compress(data)
198 x2 = co.flush()
199 self.assertRaises(zlib.error, co.flush) # second flush should not work
200 self.assertEqual(x1 + x2, datazip)
201 for v1, v2 in ((x1, x2), (bytearray(x1), bytearray(x2))):
202 dco = zlib.decompressobj()
203 y1 = dco.decompress(v1 + v2)
204 y2 = dco.flush()
205 self.assertEqual(data, y1 + y2)
206 self.assertIsInstance(dco.unconsumed_tail, bytes)
207 self.assertIsInstance(dco.unused_data, bytes)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000208
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000209 def test_compressoptions(self):
210 # specify lots of options to compressobj()
211 level = 2
212 method = zlib.DEFLATED
213 wbits = -12
214 memlevel = 9
215 strategy = zlib.Z_FILTERED
216 co = zlib.compressobj(level, method, wbits, memlevel, strategy)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000217 x1 = co.compress(HAMLET_SCENE)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000218 x2 = co.flush()
219 dco = zlib.decompressobj(wbits)
220 y1 = dco.decompress(x1 + x2)
221 y2 = dco.flush()
Neil Schemenauer6412b122004-06-05 19:34:28 +0000222 self.assertEqual(HAMLET_SCENE, y1 + y2)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000223
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000224 def test_compressincremental(self):
225 # compress object in steps, decompress object as one-shot
Neil Schemenauer6412b122004-06-05 19:34:28 +0000226 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000227 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000228 bufs = []
229 for i in range(0, len(data), 256):
230 bufs.append(co.compress(data[i:i+256]))
231 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000232 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000233
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000234 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000235 y1 = dco.decompress(b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000236 y2 = dco.flush()
237 self.assertEqual(data, y1 + y2)
238
Neil Schemenauer6412b122004-06-05 19:34:28 +0000239 def test_decompinc(self, flush=False, source=None, cx=256, dcx=64):
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000240 # compress object in steps, decompress object in steps
Neil Schemenauer6412b122004-06-05 19:34:28 +0000241 source = source or HAMLET_SCENE
242 data = source * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000243 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000244 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000245 for i in range(0, len(data), cx):
246 bufs.append(co.compress(data[i:i+cx]))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000247 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000248 combuf = b''.join(bufs)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000249
Gregory P. Smith693fc462008-09-06 20:13:06 +0000250 decombuf = zlib.decompress(combuf)
251 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000252 self.assertIsInstance(decombuf, bytes)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000253
254 self.assertEqual(data, decombuf)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000255
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000256 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000257 bufs = []
Neil Schemenauer6412b122004-06-05 19:34:28 +0000258 for i in range(0, len(combuf), dcx):
259 bufs.append(dco.decompress(combuf[i:i+dcx]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000260 self.assertEqual(b'', dco.unconsumed_tail, ########
261 "(A) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000262 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000263 self.assertEqual(b'', dco.unused_data)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000264 if flush:
265 bufs.append(dco.flush())
266 else:
267 while True:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000268 chunk = dco.decompress(b'')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000269 if chunk:
270 bufs.append(chunk)
271 else:
272 break
Guido van Rossum776152b2007-05-22 22:44:07 +0000273 self.assertEqual(b'', dco.unconsumed_tail, ########
274 "(B) uct should be b'': not %d long" %
Neil Schemenauer6412b122004-06-05 19:34:28 +0000275 len(dco.unconsumed_tail))
Amaury Forgeot d'Arce43d33a2008-07-02 20:50:16 +0000276 self.assertEqual(b'', dco.unused_data)
Guido van Rossum776152b2007-05-22 22:44:07 +0000277 self.assertEqual(data, b''.join(bufs))
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000278 # Failure means: "decompressobj with init options failed"
279
Neil Schemenauer6412b122004-06-05 19:34:28 +0000280 def test_decompincflush(self):
281 self.test_decompinc(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000282
Neil Schemenauer6412b122004-06-05 19:34:28 +0000283 def test_decompimax(self, source=None, cx=256, dcx=64):
284 # compress in steps, decompress in length-restricted steps
285 source = source or HAMLET_SCENE
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000286 # Check a decompression object with max_length specified
Neil Schemenauer6412b122004-06-05 19:34:28 +0000287 data = source * 128
288 co = zlib.compressobj()
289 bufs = []
290 for i in range(0, len(data), cx):
291 bufs.append(co.compress(data[i:i+cx]))
292 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000293 combuf = b''.join(bufs)
Neil Schemenauer6412b122004-06-05 19:34:28 +0000294 self.assertEqual(data, zlib.decompress(combuf),
295 'compressed data failure')
296
297 dco = zlib.decompressobj()
298 bufs = []
299 cb = combuf
300 while cb:
301 #max_length = 1 + len(cb)//10
302 chunk = dco.decompress(cb, dcx)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000303 self.assertFalse(len(chunk) > dcx,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000304 'chunk too big (%d>%d)' % (len(chunk), dcx))
305 bufs.append(chunk)
306 cb = dco.unconsumed_tail
307 bufs.append(dco.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000308 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Neil Schemenauer6412b122004-06-05 19:34:28 +0000309
310 def test_decompressmaxlen(self, flush=False):
311 # Check a decompression object with max_length specified
312 data = HAMLET_SCENE * 128
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000313 co = zlib.compressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000314 bufs = []
315 for i in range(0, len(data), 256):
316 bufs.append(co.compress(data[i:i+256]))
317 bufs.append(co.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000318 combuf = b''.join(bufs)
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000319 self.assertEqual(data, zlib.decompress(combuf),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000320 'compressed data failure')
321
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000322 dco = zlib.decompressobj()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000323 bufs = []
324 cb = combuf
325 while cb:
Guido van Rossumf3594102003-02-27 18:39:18 +0000326 max_length = 1 + len(cb)//10
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000327 chunk = dco.decompress(cb, max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000328 self.assertFalse(len(chunk) > max_length,
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000329 'chunk too big (%d>%d)' % (len(chunk),max_length))
330 bufs.append(chunk)
331 cb = dco.unconsumed_tail
Neil Schemenauer6412b122004-06-05 19:34:28 +0000332 if flush:
333 bufs.append(dco.flush())
334 else:
335 while chunk:
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000336 chunk = dco.decompress(b'', max_length)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000337 self.assertFalse(len(chunk) > max_length,
Neil Schemenauer6412b122004-06-05 19:34:28 +0000338 'chunk too big (%d>%d)' % (len(chunk),max_length))
339 bufs.append(chunk)
Guido van Rossum776152b2007-05-22 22:44:07 +0000340 self.assertEqual(data, b''.join(bufs), 'Wrong data retrieved')
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000341
Neil Schemenauer6412b122004-06-05 19:34:28 +0000342 def test_decompressmaxlenflush(self):
343 self.test_decompressmaxlen(flush=True)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000344
345 def test_maxlenmisc(self):
346 # Misc tests of max_length
Neil Schemenauer94afd3e2004-06-05 19:02:52 +0000347 dco = zlib.decompressobj()
Antoine Pitrou77b338b2009-12-14 18:00:06 +0000348 self.assertRaises(ValueError, dco.decompress, b"", -1)
Guido van Rossum776152b2007-05-22 22:44:07 +0000349 self.assertEqual(b'', dco.unconsumed_tail)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000350
Nadeem Vawda7619e882011-05-14 14:05:20 +0200351 def test_clear_unconsumed_tail(self):
352 # Issue #12050: calling decompress() without providing max_length
353 # should clear the unconsumed_tail attribute.
354 cdata = b"x\x9cKLJ\x06\x00\x02M\x01" # "abc"
355 dco = zlib.decompressobj()
356 ddata = dco.decompress(cdata, 1)
357 ddata += dco.decompress(dco.unconsumed_tail)
358 self.assertEqual(dco.unconsumed_tail, b"")
359
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000360 def test_flushes(self):
361 # Test flush() with the various options, using all the
362 # different levels in order to provide more variations.
363 sync_opt = ['Z_NO_FLUSH', 'Z_SYNC_FLUSH', 'Z_FULL_FLUSH']
364 sync_opt = [getattr(zlib, opt) for opt in sync_opt
365 if hasattr(zlib, opt)]
Neil Schemenauer6412b122004-06-05 19:34:28 +0000366 data = HAMLET_SCENE * 8
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000367
368 for sync in sync_opt:
369 for level in range(10):
370 obj = zlib.compressobj( level )
371 a = obj.compress( data[:3000] )
372 b = obj.flush( sync )
373 c = obj.compress( data[3000:] )
374 d = obj.flush()
Guido van Rossum776152b2007-05-22 22:44:07 +0000375 self.assertEqual(zlib.decompress(b''.join([a,b,c,d])),
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000376 data, ("Decompress failed: flush "
377 "mode=%i, level=%i") % (sync, level))
378 del obj
379
380 def test_odd_flush(self):
381 # Test for odd flushing bugs noted in 2.0, and hopefully fixed in 2.1
382 import random
383
384 if hasattr(zlib, 'Z_SYNC_FLUSH'):
385 # Testing on 17K of "random" data
386
387 # Create compressor and decompressor objects
Neil Schemenauer6412b122004-06-05 19:34:28 +0000388 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000389 dco = zlib.decompressobj()
390
391 # Try 17K of data
392 # generate random data stream
393 try:
394 # In 2.3 and later, WichmannHill is the RNG of the bug report
395 gen = random.WichmannHill()
396 except AttributeError:
397 try:
398 # 2.2 called it Random
399 gen = random.Random()
400 except AttributeError:
401 # others might simply have a single RNG
402 gen = random
403 gen.seed(1)
404 data = genblock(1, 17 * 1024, generator=gen)
405
406 # compress, sync-flush, and decompress
407 first = co.compress(data)
408 second = co.flush(zlib.Z_SYNC_FLUSH)
409 expanded = dco.decompress(first + second)
410
411 # if decompressed data is different from the input data, choke.
412 self.assertEqual(expanded, data, "17K random source doesn't match")
413
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000414 def test_empty_flush(self):
415 # Test that calling .flush() on unused objects works.
416 # (Bug #1083110 -- calling .flush() on decompress objects
417 # caused a core dump.)
418
419 co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
Benjamin Petersonc9c0f202009-06-30 23:06:06 +0000420 self.assertTrue(co.flush()) # Returns a zlib header
Andrew M. Kuchling3b585b32004-12-28 20:10:48 +0000421 dco = zlib.decompressobj()
Guido van Rossum776152b2007-05-22 22:44:07 +0000422 self.assertEqual(dco.flush(), b"") # Returns nothing
Tim Peters5a9fb3c2005-01-07 16:01:32 +0000423
Antoine Pitrouc09c92f2010-05-11 23:36:40 +0000424 def test_decompress_incomplete_stream(self):
425 # This is 'foo', deflated
426 x = b'x\x9cK\xcb\xcf\x07\x00\x02\x82\x01E'
427 # For the record
428 self.assertEqual(zlib.decompress(x), b'foo')
429 self.assertRaises(zlib.error, zlib.decompress, x[:-5])
430 # Omitting the stream end works with decompressor objects
431 # (see issue #8672).
432 dco = zlib.decompressobj()
433 y = dco.decompress(x[:-5])
434 y += dco.flush()
435 self.assertEqual(y, b'foo')
436
Nadeem Vawda39079942012-11-05 00:37:42 +0100437 def test_decompress_unused_data(self):
438 # Repeated calls to decompress() after EOF should accumulate data in
439 # dco.unused_data, instead of just storing the arg to the last call.
Nadeem Vawdaee7889d2012-11-11 02:14:36 +0100440 source = b'abcdefghijklmnopqrstuvwxyz'
441 remainder = b'0123456789'
442 y = zlib.compress(source)
443 x = y + remainder
444 for maxlen in 0, 1000:
445 for step in 1, 2, len(y), len(x):
446 dco = zlib.decompressobj()
447 data = b''
448 for i in range(0, len(x), step):
449 if i < len(y):
450 self.assertEqual(dco.unused_data, b'')
451 if maxlen == 0:
452 data += dco.decompress(x[i : i + step])
453 self.assertEqual(dco.unconsumed_tail, b'')
454 else:
455 data += dco.decompress(
456 dco.unconsumed_tail + x[i : i + step], maxlen)
457 data += dco.flush()
458 self.assertEqual(data, source)
459 self.assertEqual(dco.unconsumed_tail, b'')
460 self.assertEqual(dco.unused_data, remainder)
Nadeem Vawda39079942012-11-05 00:37:42 +0100461
Nadeem Vawda7ee95552012-11-11 03:15:32 +0100462 def test_flush_with_freed_input(self):
463 # Issue #16411: decompressor accesses input to last decompress() call
464 # in flush(), even if this object has been freed in the meanwhile.
465 input1 = b'abcdefghijklmnopqrstuvwxyz'
466 input2 = b'QWERTYUIOPASDFGHJKLZXCVBNM'
467 data = zlib.compress(input1)
468 dco = zlib.decompressobj()
469 dco.decompress(data, 1)
470 del data
471 data = zlib.compress(input2)
472 self.assertEqual(dco.flush(), input1[1:])
473
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000474 if hasattr(zlib.compressobj(), "copy"):
475 def test_compresscopy(self):
476 # Test copying a compression object
477 data0 = HAMLET_SCENE
Guido van Rossum776152b2007-05-22 22:44:07 +0000478 data1 = bytes(str(HAMLET_SCENE, "ascii").swapcase(), "ascii")
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000479 c0 = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
480 bufs0 = []
481 bufs0.append(c0.compress(data0))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000482
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000483 c1 = c0.copy()
484 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000485
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000486 bufs0.append(c0.compress(data0))
487 bufs0.append(c0.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000488 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000489
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000490 bufs1.append(c1.compress(data1))
491 bufs1.append(c1.flush())
Guido van Rossum776152b2007-05-22 22:44:07 +0000492 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000493
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000494 self.assertEqual(zlib.decompress(s0),data0+data0)
495 self.assertEqual(zlib.decompress(s1),data0+data1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000496
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000497 def test_badcompresscopy(self):
498 # Test copying a compression object in an inconsistent state
499 c = zlib.compressobj()
500 c.compress(HAMLET_SCENE)
501 c.flush()
502 self.assertRaises(ValueError, c.copy)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000503
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000504 if hasattr(zlib.decompressobj(), "copy"):
505 def test_decompresscopy(self):
506 # Test copying a decompression object
507 data = HAMLET_SCENE
508 comp = zlib.compress(data)
Gregory P. Smith693fc462008-09-06 20:13:06 +0000509 # Test type of return value
Ezio Melottie9615932010-01-24 19:26:24 +0000510 self.assertIsInstance(comp, bytes)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000511
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000512 d0 = zlib.decompressobj()
513 bufs0 = []
514 bufs0.append(d0.decompress(comp[:32]))
Thomas Wouters477c8d52006-05-27 19:21:47 +0000515
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000516 d1 = d0.copy()
517 bufs1 = bufs0[:]
Thomas Wouters477c8d52006-05-27 19:21:47 +0000518
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000519 bufs0.append(d0.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000520 s0 = b''.join(bufs0)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000521
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000522 bufs1.append(d1.decompress(comp[32:]))
Guido van Rossum776152b2007-05-22 22:44:07 +0000523 s1 = b''.join(bufs1)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000524
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000525 self.assertEqual(s0,s1)
526 self.assertEqual(s0,data)
Thomas Wouters477c8d52006-05-27 19:21:47 +0000527
Thomas Wouters0e3f5912006-08-11 14:57:12 +0000528 def test_baddecompresscopy(self):
529 # Test copying a compression object in an inconsistent state
530 data = zlib.compress(HAMLET_SCENE)
531 d = zlib.decompressobj()
532 d.decompress(data)
533 d.flush()
534 self.assertRaises(ValueError, d.copy)
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000535
Antoine Pitrou89562712010-05-07 17:04:02 +0000536 # Memory use of the following functions takes into account overallocation
537
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200538 @bigmemtest(size=_1G + 1024 * 1024, memuse=3)
Antoine Pitrou89562712010-05-07 17:04:02 +0000539 def test_big_compress_buffer(self, size):
540 c = zlib.compressobj(1)
541 compress = lambda s: c.compress(s) + c.flush()
542 self.check_big_compress_buffer(size, compress)
543
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200544 @bigmemtest(size=_1G + 1024 * 1024, memuse=2)
Antoine Pitrou89562712010-05-07 17:04:02 +0000545 def test_big_decompress_buffer(self, size):
546 d = zlib.decompressobj()
547 decompress = lambda s: d.decompress(s) + d.flush()
548 self.check_big_decompress_buffer(size, decompress)
549
Antoine Pitrou94190bb2011-10-04 10:22:36 +0200550 @bigmemtest(size=_4G + 100, memuse=1)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200551 def test_length_overflow(self, size):
552 if size < _4G + 100:
553 self.skipTest("not enough free memory, need at least 4 GB")
554 data = b'x' * size
Nadeem Vawda1161a9c2011-05-15 00:48:24 +0200555 c = zlib.compressobj(1)
556 d = zlib.decompressobj()
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200557 try:
Nadeem Vawda1161a9c2011-05-15 00:48:24 +0200558 self.assertRaises(OverflowError, c.compress, data)
559 self.assertRaises(OverflowError, d.decompress, data)
Nadeem Vawda0c3d96a2011-05-15 00:19:50 +0200560 finally:
561 data = None
562
Antoine Pitrou89562712010-05-07 17:04:02 +0000563
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000564def genblock(seed, length, step=1024, generator=random):
565 """length-byte stream of random data from a seed (in step-byte blocks)."""
566 if seed is not None:
567 generator.seed(seed)
568 randint = generator.randint
569 if length < step or step < 2:
570 step = length
Guido van Rossum776152b2007-05-22 22:44:07 +0000571 blocks = bytes()
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000572 for i in range(0, length, step):
Guido van Rossum776152b2007-05-22 22:44:07 +0000573 blocks += bytes(randint(0, 255) for x in range(step))
574 return blocks
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000575
576
577
578def choose_lines(source, number, seed=None, generator=random):
579 """Return a list of number lines randomly chosen from the source"""
580 if seed is not None:
581 generator.seed(seed)
582 sources = source.split('\n')
583 return [generator.choice(sources) for n in range(number)]
584
585
586
Guido van Rossum776152b2007-05-22 22:44:07 +0000587HAMLET_SCENE = b"""
Fred Drake004d5e62000-10-23 17:22:08 +0000588LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000589
590 O, fear me not.
591 I stay too long: but here my father comes.
592
593 Enter POLONIUS
594
595 A double blessing is a double grace,
596 Occasion smiles upon a second leave.
597
Fred Drake004d5e62000-10-23 17:22:08 +0000598LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000599
600 Yet here, Laertes! aboard, aboard, for shame!
601 The wind sits in the shoulder of your sail,
602 And you are stay'd for. There; my blessing with thee!
603 And these few precepts in thy memory
604 See thou character. Give thy thoughts no tongue,
605 Nor any unproportioned thought his act.
606 Be thou familiar, but by no means vulgar.
607 Those friends thou hast, and their adoption tried,
608 Grapple them to thy soul with hoops of steel;
609 But do not dull thy palm with entertainment
610 Of each new-hatch'd, unfledged comrade. Beware
611 Of entrance to a quarrel, but being in,
612 Bear't that the opposed may beware of thee.
613 Give every man thy ear, but few thy voice;
614 Take each man's censure, but reserve thy judgment.
615 Costly thy habit as thy purse can buy,
616 But not express'd in fancy; rich, not gaudy;
617 For the apparel oft proclaims the man,
618 And they in France of the best rank and station
619 Are of a most select and generous chief in that.
620 Neither a borrower nor a lender be;
621 For loan oft loses both itself and friend,
622 And borrowing dulls the edge of husbandry.
623 This above all: to thine ownself be true,
624 And it must follow, as the night the day,
625 Thou canst not then be false to any man.
626 Farewell: my blessing season this in thee!
627
Fred Drake004d5e62000-10-23 17:22:08 +0000628LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000629
630 Most humbly do I take my leave, my lord.
631
Fred Drake004d5e62000-10-23 17:22:08 +0000632LORD POLONIUS
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000633
634 The time invites you; go; your servants tend.
635
Fred Drake004d5e62000-10-23 17:22:08 +0000636LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000637
638 Farewell, Ophelia; and remember well
639 What I have said to you.
640
Fred Drake004d5e62000-10-23 17:22:08 +0000641OPHELIA
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000642
643 'Tis in my memory lock'd,
644 And you yourself shall keep the key of it.
645
Fred Drake004d5e62000-10-23 17:22:08 +0000646LAERTES
Jeremy Hylton6eb4b6a1997-08-15 15:59:43 +0000647
648 Farewell.
649"""
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000650
651
652def test_main():
Benjamin Petersonee8712c2008-05-20 21:35:26 +0000653 support.run_unittest(
Walter Dörwald21d3a322003-05-01 17:45:56 +0000654 ChecksumTestCase,
Antoine Pitrouf3d22752011-02-21 18:09:00 +0000655 ChecksumBigBufferTestCase,
Walter Dörwald21d3a322003-05-01 17:45:56 +0000656 ExceptionTestCase,
657 CompressTestCase,
658 CompressObjectTestCase
659 )
Guido van Rossum7d9ea502003-02-03 20:45:52 +0000660
661if __name__ == "__main__":
Guido van Rossum776152b2007-05-22 22:44:07 +0000662 unittest.main() # XXX
663 ###test_main()