cpython: 0b5211d19a14 (original) (raw)
Mercurial > cpython
changeset 70118:0b5211d19a14 3.1
Issue #8650: Make zlib.[de]compressobj().[de]compress() 64-bit clean. Raise an OverflowError if the input data is too large, instead of silently truncating the input and returning an incorrect result. [#8650]
Nadeem Vawda nadeem.vawda@gmail.com | |
---|---|
date | Sun, 15 May 2011 00:19:50 +0200 |
parents | 288c26e36d02 |
children | 3ff862d05d18 8db300ceceb7 |
files | Lib/test/test_zlib.py Misc/NEWS Modules/zlibmodule.c |
diffstat | 3 files changed, 39 insertions(+), 14 deletions(-)[+] [-] Lib/test/test_zlib.py 11 Misc/NEWS 5 Modules/zlibmodule.c 37 |
line wrap: on
line diff
--- a/Lib/test/test_zlib.py +++ b/Lib/test/test_zlib.py @@ -523,6 +523,17 @@ class CompressObjectTestCase(BaseCompres decompress = lambda s: d.decompress(s) + d.flush() self.check_big_decompress_buffer(size, decompress)
- @precisionbigmemtest(size=_4G + 100, memuse=1)
- def test_length_overflow(self, size):
if size < _4G + 100:[](#l1.9)
self.skipTest("not enough free memory, need at least 4 GB")[](#l1.10)
data = b'x' * size[](#l1.11)
try:[](#l1.12)
self.assertRaises(OverflowError, zlib.compress, data, 1)[](#l1.13)
self.assertRaises(OverflowError, zlib.decompress, data)[](#l1.14)
finally:[](#l1.15)
data = None[](#l1.16)
+ def genblock(seed, length, step=1024, generator=random): """length-byte stream of random data from a seed (in step-byte blocks)."""
--- a/Misc/NEWS +++ b/Misc/NEWS @@ -69,6 +69,11 @@ Core and Builtins 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 attribute when called without a max_length argument.
--- a/Modules/zlibmodule.c +++ b/Modules/zlibmodule.c @@ -420,22 +420,26 @@ PyDoc_STRVAR(comp_compress__doc__, static PyObject * PyZlib_objcompress(compobject *self, PyObject *args) {
- PyObject *RetVal = NULL; Py_buffer pinput; Byte input; unsigned long start_total_out; if (!PyArg_ParseTuple(args, "y:compress", &pinput)) return NULL;
- if (pinput.len > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,[](#l3.20)
"Size does not fit in an unsigned int");[](#l3.21)
goto error_outer;[](#l3.22)
- } input = pinput.buf; inplen = pinput.len;
- if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) {
PyBuffer_Release(&pinput);[](#l3.28)
return NULL;[](#l3.29)
- }
ENTER_ZLIB(self); @@ -484,6 +488,7 @@ PyZlib_objcompress(compobject *self, PyO error: LEAVE_ZLIB(self);
- error_outer: PyBuffer_Release(&pinput); return RetVal; } @@ -502,9 +507,10 @@ PyDoc_STRVAR(decomp_decompress__doc__, static PyObject * PyZlib_objdecompress(compobject *self, PyObject *args) {
- PyObject *RetVal = NULL; Py_buffer pinput; Byte *input; unsigned long start_total_out; @@ -512,22 +518,24 @@ PyZlib_objdecompress(compobject self, P if (!PyArg_ParseTuple(args, "y|i:decompress", &pinput, &max_length)) return NULL;
- if (pinput.len > UINT_MAX) {
PyErr_SetString(PyExc_OverflowError,[](#l3.62)
"Size does not fit in an unsigned int");[](#l3.63)
goto error_outer;[](#l3.64)
- } input = pinput.buf; inplen = pinput.len; if (max_length < 0) {
PyBuffer_Release(&pinput);[](#l3.69) PyErr_SetString(PyExc_ValueError,[](#l3.70) "max_length must be greater than zero");[](#l3.71)
return NULL;[](#l3.72)
} /* limit amount of data allocated to max_length */ if (max_length && length > max_length) length = max_length;goto error_outer;[](#l3.73)
- if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) {
PyBuffer_Release(&pinput);[](#l3.80)
return NULL;[](#l3.81)
- }
ENTER_ZLIB(self); @@ -621,6 +629,7 @@ PyZlib_objdecompress(compobject *self, P error: LEAVE_ZLIB(self);