Kaydet (Commit) 7d9ea501 authored tarafından Guido van Rossum's avatar Guido van Rossum

- Thanks to Scott David Daniels, a subtle bug in how the zlib

  extension implemented flush() was fixed.  Scott also rewrite the
  zlib test suite using the unittest module.  (SF bug #640230 and
  patch #678531.)

Backport candidate I think.
üst 94c30c01
test_zlib
0xe5c1a120 0x43b6aa94
0xbd602f7 0xbd602f7
expecting Bad compression level
expecting Invalid initialization option
expecting Invalid initialization option
normal compression/decompression succeeded
compress/decompression obj succeeded
decompress with init options succeeded
decompressobj with init options succeeded
should be '': ''
max_length decompressobj succeeded
unconsumed_tail should be '': ''
Testing on 17K of random data
This diff is collapsed.
......@@ -123,6 +123,7 @@ John Cugini
Andrew Dalke
Lars Damerow
Eric Daniel
Scott David Daniels
Ben Darnell
Jonathan Dasteel
John DeGood
......
......@@ -33,6 +33,11 @@ Core and builtins
Extension modules
-----------------
- Thanks to Scott David Daniels, a subtle bug in how the zlib
extension implemented flush() was fixed. Scott also rewrite the
zlib test suite using the unittest module. (SF bug #640230 and
patch #678531.)
- Added an itertools module containing high speed, memory efficient
looping constructs inspired by tools from Haskell and SML.
......
......@@ -656,26 +656,57 @@ PyDoc_STRVAR(decomp_flush__doc__,
static PyObject *
PyZlib_unflush(compobject *self, PyObject *args)
/*decompressor flush is a no-op because all pending data would have been
flushed by the decompress method. However, this routine previously called
inflateEnd, causing any further decompress or flush calls to raise
exceptions. This behaviour has been preserved.*/
{
int err;
int err, length = DEFAULTALLOC;
PyObject * retval = NULL;
unsigned long start_total_out;
if (!PyArg_ParseTuple(args, ""))
if (!PyArg_ParseTuple(args, "|i:flush", &length))
return NULL;
if (!(retval = PyString_FromStringAndSize(NULL, length)))
return NULL;
ENTER_ZLIB
err = inflateEnd(&(self->zst));
if (err != Z_OK)
zlib_error(self->zst, err, "from inflateEnd()");
else {
self->is_initialised = 0;
retval = PyString_FromStringAndSize(NULL, 0);
start_total_out = self->zst.total_out;
self->zst.avail_out = length;
self->zst.next_out = (Byte *)PyString_AS_STRING(retval);
Py_BEGIN_ALLOW_THREADS
err = inflate(&(self->zst), Z_FINISH);
Py_END_ALLOW_THREADS
/* while Z_OK and the output buffer is full, there might be more output,
so extend the output buffer and try again */
while ((err == Z_OK || err == Z_BUF_ERROR) && self->zst.avail_out == 0) {
if (_PyString_Resize(&retval, length << 1) < 0)
goto error;
self->zst.next_out = (Byte *)PyString_AS_STRING(retval) + length;
self->zst.avail_out = length;
length = length << 1;
Py_BEGIN_ALLOW_THREADS
err = inflate(&(self->zst), Z_FINISH);
Py_END_ALLOW_THREADS
}
/* If flushmode is Z_FINISH, we also have to call deflateEnd() to free
various data structures. Note we should only get Z_STREAM_END when
flushmode is Z_FINISH */
if (err == Z_STREAM_END) {
err = inflateEnd(&(self->zst));
self->is_initialised = 0;
if (err != Z_OK) {
zlib_error(self->zst, err, "from inflateEnd()");
Py_DECREF(retval);
retval = NULL;
goto error;
}
}
_PyString_Resize(&retval, self->zst.total_out - start_total_out);
error:
LEAVE_ZLIB
......@@ -868,6 +899,8 @@ PyInit_zlib(void)
if (ver != NULL)
PyModule_AddObject(m, "ZLIB_VERSION", ver);
PyModule_AddStringConstant(m, "__version__", "1.0");
#ifdef WITH_THREAD
zlib_lock = PyThread_allocate_lock();
#endif /* WITH_THREAD */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment