diff -r 931e1bc090f6 Modules/zlibmodule.c --- a/Modules/zlibmodule.c Mon Jun 24 23:02:51 2013 +0200 +++ b/Modules/zlibmodule.c Mon Jun 24 23:03:05 2013 +0200 @@ -238,11 +238,11 @@ PyZlib_decompress(PyObject *self, PyObje unsigned int length; int err; int wsize=DEF_WBITS; - Py_ssize_t r_strlen=DEFAULTALLOC; + Py_ssize_t bufsize=DEFAULTALLOC, new_bufsize; z_stream zst; if (!PyArg_ParseTuple(args, "y*|in:decompress", - &pinput, &wsize, &r_strlen)) + &pinput, &wsize, &bufsize)) return NULL; if (pinput.len > UINT_MAX) { @@ -250,16 +250,22 @@ PyZlib_decompress(PyObject *self, PyObje "Size does not fit in an unsigned int"); goto error; } + + if (bufsize <= 0) + bufsize = 1; + if (bufsize > UINT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "bufsize does not fit in an unsigned int"); + goto error; + } + input = pinput.buf; length = (unsigned int)pinput.len; - if (r_strlen <= 0) - r_strlen = 1; + zst.avail_in = length; + zst.avail_out = (unsigned int)bufsize; - zst.avail_in = length; - zst.avail_out = r_strlen; - - if (!(result_str = PyBytes_FromStringAndSize(NULL, r_strlen))) + if (!(result_str = PyBytes_FromStringAndSize(NULL, bufsize))) goto error; zst.zalloc = (alloc_func)NULL; @@ -303,14 +309,18 @@ PyZlib_decompress(PyObject *self, PyObje /* fall through */ case(Z_OK): /* need more memory */ - if (_PyBytes_Resize(&result_str, r_strlen << 1) < 0) { + if (bufsize <= (UINT_MAX >> 1)) + new_bufsize = bufsize << 1; + else + new_bufsize = UINT_MAX; + if (_PyBytes_Resize(&result_str, new_bufsize) < 0) { inflateEnd(&zst); goto error; } zst.next_out = - (unsigned char *)PyBytes_AS_STRING(result_str) + r_strlen; - zst.avail_out = r_strlen; - r_strlen = r_strlen << 1; + (unsigned char *)PyBytes_AS_STRING(result_str) + bufsize; + zst.avail_out = bufsize; + bufsize = new_bufsize; break; default: inflateEnd(&zst); @@ -353,6 +363,12 @@ PyZlib_compressobj(PyObject *selfptr, Py &memLevel, &strategy, &zdict)) return NULL; + if (zdict.len > UINT_MAX) { + PyErr_SetString(PyExc_OverflowError, + "zdict length does not fit in an unsigned int"); + goto error; + } + self = newcompobject(&Comptype); if (self==NULL) goto error; @@ -367,7 +383,7 @@ PyZlib_compressobj(PyObject *selfptr, Py if (zdict.buf == NULL) { goto success; } else { - err = deflateSetDictionary(&self->zst, zdict.buf, zdict.len); + err = deflateSetDictionary(&self->zst, zdict.buf, (int)zdict.len); switch (err) { case (Z_OK): goto success; @@ -490,7 +506,7 @@ PyZlib_objcompress(compobject *self, PyO { int err; unsigned int inplen; - Py_ssize_t length = DEFAULTALLOC; + Py_ssize_t length = DEFAULTALLOC, new_length; PyObject *RetVal = NULL; Py_buffer pinput; Byte *input; @@ -504,7 +520,7 @@ PyZlib_objcompress(compobject *self, PyO goto error_outer; } input = pinput.buf; - inplen = pinput.len; + inplen = (unsigned int)pinput.len; if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) goto error_outer; @@ -514,7 +530,7 @@ PyZlib_objcompress(compobject *self, PyO start_total_out = self->zst.total_out; self->zst.avail_in = inplen; self->zst.next_in = input; - self->zst.avail_out = length; + self->zst.avail_out = Py_SAFE_DOWNCAST(length, Py_ssize_t, unsigned int); self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal); Py_BEGIN_ALLOW_THREADS @@ -524,7 +540,11 @@ PyZlib_objcompress(compobject *self, PyO /* 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 && self->zst.avail_out == 0) { - if (_PyBytes_Resize(&RetVal, length << 1) < 0) { + if (length <= (UINT_MAX >> 1)) + new_length = length << 1; + else + new_length = UINT_MAX; + if (_PyBytes_Resize(&RetVal, new_length) < 0) { Py_DECREF(RetVal); RetVal = NULL; goto error; @@ -532,7 +552,7 @@ PyZlib_objcompress(compobject *self, PyO self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal) + length; self->zst.avail_out = length; - length = length << 1; + length = new_length; Py_BEGIN_ALLOW_THREADS err = deflate(&(self->zst), Z_NO_FLUSH); @@ -619,11 +639,9 @@ static PyObject * PyZlib_objdecompress(compobject *self, PyObject *args) { int err, max_length = 0; - unsigned int inplen; - Py_ssize_t old_length, length = DEFAULTALLOC; + unsigned int length = DEFAULTALLOC, old_length; PyObject *RetVal = NULL; Py_buffer pinput; - Byte *input; unsigned long start_total_out; if (!PyArg_ParseTuple(args, "y*|i:decompress", &pinput, @@ -634,8 +652,6 @@ PyZlib_objdecompress(compobject *self, P "Size does not fit in an unsigned int"); goto error_outer; } - input = pinput.buf; - inplen = pinput.len; if (max_length < 0) { PyErr_SetString(PyExc_ValueError, "max_length must be greater than zero"); @@ -643,7 +659,7 @@ PyZlib_objdecompress(compobject *self, P } /* limit amount of data allocated to max_length */ - if (max_length && length > max_length) + if (max_length && length > (unsigned int)max_length) length = max_length; if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) goto error_outer; @@ -651,8 +667,8 @@ PyZlib_objdecompress(compobject *self, P ENTER_ZLIB(self); start_total_out = self->zst.total_out; - self->zst.avail_in = inplen; - self->zst.next_in = input; + self->zst.avail_in = (unsigned int)pinput.len; + self->zst.next_in = pinput.buf; self->zst.avail_out = length; self->zst.next_out = (unsigned char *)PyBytes_AS_STRING(RetVal); @@ -667,7 +683,8 @@ PyZlib_objdecompress(compobject *self, P RetVal = NULL; goto error; } - err = inflateSetDictionary(&(self->zst), zdict_buf.buf, zdict_buf.len); + err = inflateSetDictionary(&(self->zst), + zdict_buf.buf, (unsigned int)zdict_buf.len); PyBuffer_Release(&zdict_buf); if (err != Z_OK) { zlib_error(self->zst, err, "while decompressing data"); @@ -688,14 +705,14 @@ PyZlib_objdecompress(compobject *self, P /* If max_length set, don't continue decompressing if we've already reached the limit. */ - if (max_length && length >= max_length) + if (max_length && length >= (unsigned int)max_length) break; /* otherwise, ... */ old_length = length; length = length << 1; - if (max_length && length > max_length) - length = max_length; + if (max_length && length > (unsigned int)max_length) + length = (unsigned int)max_length; if (_PyBytes_Resize(&RetVal, length) < 0) { Py_DECREF(RetVal); @@ -961,6 +978,7 @@ PyZlib_unflush(compobject *self, PyObjec int err, length = DEFAULTALLOC; PyObject * retval = NULL; unsigned long start_total_out; + Py_ssize_t size; if (!PyArg_ParseTuple(args, "|i:flush", &length)) return NULL; @@ -971,11 +989,12 @@ PyZlib_unflush(compobject *self, PyObjec if (!(retval = PyBytes_FromStringAndSize(NULL, length))) return NULL; - ENTER_ZLIB(self); + size = PyBytes_GET_SIZE(self->unconsumed_tail); + start_total_out = self->zst.total_out; - self->zst.avail_in = PyBytes_GET_SIZE(self->unconsumed_tail); + self->zst.avail_in = Py_SAFE_DOWNCAST(size, Py_ssize_t, unsigned int); self->zst.next_in = (Byte *)PyBytes_AS_STRING(self->unconsumed_tail); self->zst.avail_out = length; self->zst.next_out = (Byte *)PyBytes_AS_STRING(retval);