[Bug #1083110] calling .flush() on decompress objects causes a segfault due to an uninitialized pointer: fixes the problem and adds a test case

This commit is contained in:
Andrew M. Kuchling 2004-12-28 20:10:48 +00:00
parent 078824e4f6
commit 3b585b30c0
3 changed files with 18 additions and 1 deletions

View File

@ -290,6 +290,16 @@ class CompressObjectTestCase(unittest.TestCase):
# if decompressed data is different from the input data, choke. # if decompressed data is different from the input data, choke.
self.assertEqual(expanded, data, "17K random source doesn't match") self.assertEqual(expanded, data, "17K random source doesn't match")
def test_empty_flush(self):
# Test that calling .flush() on unused objects works.
# (Bug #1083110 -- calling .flush() on decompress objects
# caused a core dump.)
co = zlib.compressobj(zlib.Z_BEST_COMPRESSION)
self.failUnless(co.flush()) # Returns a zlib header
dco = zlib.decompressobj()
self.assertEqual(dco.flush(), "") # Returns nothing
def genblock(seed, length, step=1024, generator=random): def genblock(seed, length, step=1024, generator=random):
"""length-byte stream of random data from a seed (in step-byte blocks).""" """length-byte stream of random data from a seed (in step-byte blocks)."""

View File

@ -64,6 +64,9 @@ Library
once when a size argument is given. This prevents a buffer overflow in the once when a size argument is given. This prevents a buffer overflow in the
tokenizer with very long source lines. tokenizer with very long source lines.
- Bug #1083110: ``zlib.decompress.flush()`` would segfault if called immediately
after creating the object, without any intervening ``.decompress()`` calls.
Build Build
----- -----

View File

@ -301,6 +301,8 @@ PyZlib_compressobj(PyObject *selfptr, PyObject *args)
return(NULL); return(NULL);
self->zst.zalloc = (alloc_func)NULL; self->zst.zalloc = (alloc_func)NULL;
self->zst.zfree = (free_func)Z_NULL; self->zst.zfree = (free_func)Z_NULL;
self->zst.next_in = NULL;
self->zst.avail_in = 0;
err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy); err = deflateInit2(&self->zst, level, method, wbits, memLevel, strategy);
switch(err) { switch(err) {
case (Z_OK): case (Z_OK):
@ -335,6 +337,8 @@ PyZlib_decompressobj(PyObject *selfptr, PyObject *args)
return(NULL); return(NULL);
self->zst.zalloc = (alloc_func)NULL; self->zst.zalloc = (alloc_func)NULL;
self->zst.zfree = (free_func)Z_NULL; self->zst.zfree = (free_func)Z_NULL;
self->zst.next_in = NULL;
self->zst.avail_in = 0;
err = inflateInit2(&self->zst, wbits); err = inflateInit2(&self->zst, wbits);
switch(err) { switch(err) {
case (Z_OK): case (Z_OK):
@ -516,7 +520,7 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
Py_END_ALLOW_THREADS Py_END_ALLOW_THREADS
} }
/* Not all of the compressed data could be accomodated in the output buffer /* Not all of the compressed data could be accommodated in the output buffer
of specified size. Return the unconsumed tail in an attribute.*/ of specified size. Return the unconsumed tail in an attribute.*/
if(max_length) { if(max_length) {
Py_DECREF(self->unconsumed_tail); Py_DECREF(self->unconsumed_tail);