From 7619e88adb27d1cd167483304cd1514812b68039 Mon Sep 17 00:00:00 2001 From: Nadeem Vawda Date: Sat, 14 May 2011 14:05:20 +0200 Subject: Issue #12050: zlib.decompressobj().decompress() now clears the unconsumed_tail attribute when called without a max_length argument. --- Lib/test/test_zlib.py | 9 +++++++++ Misc/NEWS | 3 +++ Modules/zlibmodule.c | 19 ++++++++++++------- 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_zlib.py b/Lib/test/test_zlib.py index 7593c06..f991900 100644 --- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -350,6 +350,15 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase): self.assertRaises(ValueError, dco.decompress, b"", -1) self.assertEqual(b'', dco.unconsumed_tail) + def test_clear_unconsumed_tail(self): + # Issue #12050: calling decompress() without providing max_length + # should clear the unconsumed_tail attribute. + cdata = b"x\x9cKLJ\x06\x00\x02M\x01" # "abc" + dco = zlib.decompressobj() + ddata = dco.decompress(cdata, 1) + ddata += dco.decompress(dco.unconsumed_tail) + self.assertEqual(dco.unconsumed_tail, b"") + def test_flushes(self): # Test flush() with the various options, using all the # different levels in order to provide more variations. diff --git a/Misc/NEWS b/Misc/NEWS index f96ed7b..06c1d62 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -69,6 +69,9 @@ Core and Builtins Library ------- +- Issue #12050: zlib.decompressobj().decompress() now clears the unconsumed_tail + attribute when called without a max_length argument. + - Issue #12062: Fix a flushing bug when doing a certain type of I/O sequence on a file opened in read+write mode (namely: reading, seeking a bit forward, writing, then seeking before the previous write but still within buffered diff --git a/Modules/zlibmodule.c b/Modules/zlibmodule.c index c78cf42..c0dd7cd 100644 --- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -560,17 +560,22 @@ PyZlib_objdecompress(compobject *self, PyObject *args) Py_END_ALLOW_THREADS } - /* Not all of the compressed data could be accommodated in the output buffer - of specified size. Return the unconsumed tail in an attribute.*/ if(max_length) { + /* Not all of the compressed data could be accommodated in a buffer of + the specified size. Return the unconsumed tail in an attribute. */ Py_DECREF(self->unconsumed_tail); self->unconsumed_tail = PyBytes_FromStringAndSize((char *)self->zst.next_in, self->zst.avail_in); - if(!self->unconsumed_tail) { - Py_DECREF(RetVal); - RetVal = NULL; - goto error; - } + } + else if (PyBytes_GET_SIZE(self->unconsumed_tail) > 0) { + /* All of the compressed data was consumed. Clear unconsumed_tail. */ + Py_DECREF(self->unconsumed_tail); + self->unconsumed_tail = PyBytes_FromStringAndSize("", 0); + } + if (self->unconsumed_tail == NULL) { + Py_DECREF(RetVal); + RetVal = NULL; + goto error; } /* The end of the compressed data has been reached, so set the -- cgit v0.12