merge heads

This commit is contained in:
Gregory P. Smith 2011-05-14 15:33:43 -07:00
commit 11ddc999e0
3 changed files with 39 additions and 14 deletions

View File

@ -523,6 +523,17 @@ class CompressObjectTestCase(BaseCompressTestCase, unittest.TestCase):
decompress = lambda s: d.decompress(s) + d.flush() decompress = lambda s: d.decompress(s) + d.flush()
self.check_big_decompress_buffer(size, decompress) self.check_big_decompress_buffer(size, decompress)
@precisionbigmemtest(size=_4G + 100, memuse=1)
def test_length_overflow(self, size):
if size < _4G + 100:
self.skipTest("not enough free memory, need at least 4 GB")
data = b'x' * size
try:
self.assertRaises(OverflowError, zlib.compress, data, 1)
self.assertRaises(OverflowError, zlib.decompress, data)
finally:
data = None
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

@ -90,6 +90,11 @@ Core and Builtins
Library Library
------- -------
- Issue #8650: Make zlib module 64-bit clean. compress(), decompress() and
their incremental counterparts now raise OverflowError if given an input
larger than 4GB, instead of silently truncating the input and returning
an incorrect result.
- Issue #12050: zlib.decompressobj().decompress() now clears the unconsumed_tail - Issue #12050: zlib.decompressobj().decompress() now clears the unconsumed_tail
attribute when called without a max_length argument. attribute when called without a max_length argument.

View File

@ -420,22 +420,26 @@ PyDoc_STRVAR(comp_compress__doc__,
static PyObject * static PyObject *
PyZlib_objcompress(compobject *self, PyObject *args) PyZlib_objcompress(compobject *self, PyObject *args)
{ {
int err, inplen; int err;
unsigned int inplen;
Py_ssize_t length = DEFAULTALLOC; Py_ssize_t length = DEFAULTALLOC;
PyObject *RetVal; PyObject *RetVal = NULL;
Py_buffer pinput; Py_buffer pinput;
Byte *input; Byte *input;
unsigned long start_total_out; unsigned long start_total_out;
if (!PyArg_ParseTuple(args, "y*:compress", &pinput)) if (!PyArg_ParseTuple(args, "y*:compress", &pinput))
return NULL; return NULL;
if (pinput.len > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"Size does not fit in an unsigned int");
goto error_outer;
}
input = pinput.buf; input = pinput.buf;
inplen = pinput.len; inplen = pinput.len;
if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) { if (!(RetVal = PyBytes_FromStringAndSize(NULL, length)))
PyBuffer_Release(&pinput); goto error_outer;
return NULL;
}
ENTER_ZLIB(self); ENTER_ZLIB(self);
@ -484,6 +488,7 @@ PyZlib_objcompress(compobject *self, PyObject *args)
error: error:
LEAVE_ZLIB(self); LEAVE_ZLIB(self);
error_outer:
PyBuffer_Release(&pinput); PyBuffer_Release(&pinput);
return RetVal; return RetVal;
} }
@ -502,9 +507,10 @@ PyDoc_STRVAR(decomp_decompress__doc__,
static PyObject * static PyObject *
PyZlib_objdecompress(compobject *self, PyObject *args) PyZlib_objdecompress(compobject *self, PyObject *args)
{ {
int err, inplen, max_length = 0; int err, max_length = 0;
unsigned int inplen;
Py_ssize_t old_length, length = DEFAULTALLOC; Py_ssize_t old_length, length = DEFAULTALLOC;
PyObject *RetVal; PyObject *RetVal = NULL;
Py_buffer pinput; Py_buffer pinput;
Byte *input; Byte *input;
unsigned long start_total_out; unsigned long start_total_out;
@ -512,22 +518,24 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
if (!PyArg_ParseTuple(args, "y*|i:decompress", &pinput, if (!PyArg_ParseTuple(args, "y*|i:decompress", &pinput,
&max_length)) &max_length))
return NULL; return NULL;
if (pinput.len > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,
"Size does not fit in an unsigned int");
goto error_outer;
}
input = pinput.buf; input = pinput.buf;
inplen = pinput.len; inplen = pinput.len;
if (max_length < 0) { if (max_length < 0) {
PyBuffer_Release(&pinput);
PyErr_SetString(PyExc_ValueError, PyErr_SetString(PyExc_ValueError,
"max_length must be greater than zero"); "max_length must be greater than zero");
return NULL; goto error_outer;
} }
/* limit amount of data allocated to max_length */ /* limit amount of data allocated to max_length */
if (max_length && length > max_length) if (max_length && length > max_length)
length = max_length; length = max_length;
if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) { if (!(RetVal = PyBytes_FromStringAndSize(NULL, length)))
PyBuffer_Release(&pinput); goto error_outer;
return NULL;
}
ENTER_ZLIB(self); ENTER_ZLIB(self);
@ -621,6 +629,7 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
error: error:
LEAVE_ZLIB(self); LEAVE_ZLIB(self);
error_outer:
PyBuffer_Release(&pinput); PyBuffer_Release(&pinput);
return RetVal; return RetVal;
} }