Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 11ddc99

Browse files
committed
merge heads
2 parents 873cab2 + 565d659 commit 11ddc99

3 files changed

Lines changed: 39 additions & 14 deletions

File tree

Lib/test/test_zlib.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,17 @@ def test_big_decompress_buffer(self, size):
523523
decompress = lambda s: d.decompress(s) + d.flush()
524524
self.check_big_decompress_buffer(size, decompress)
525525

526+
@precisionbigmemtest(size=_4G + 100, memuse=1)
527+
def test_length_overflow(self, size):
528+
if size < _4G + 100:
529+
self.skipTest("not enough free memory, need at least 4 GB")
530+
data = b'x' * size
531+
try:
532+
self.assertRaises(OverflowError, zlib.compress, data, 1)
533+
self.assertRaises(OverflowError, zlib.decompress, data)
534+
finally:
535+
data = None
536+
526537

527538
def genblock(seed, length, step=1024, generator=random):
528539
"""length-byte stream of random data from a seed (in step-byte blocks)."""

Misc/NEWS

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,11 @@ Core and Builtins
9090
Library
9191
-------
9292

93+
- Issue #8650: Make zlib module 64-bit clean. compress(), decompress() and
94+
their incremental counterparts now raise OverflowError if given an input
95+
larger than 4GB, instead of silently truncating the input and returning
96+
an incorrect result.
97+
9398
- Issue #12050: zlib.decompressobj().decompress() now clears the unconsumed_tail
9499
attribute when called without a max_length argument.
95100

Modules/zlibmodule.c

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -420,22 +420,26 @@ PyDoc_STRVAR(comp_compress__doc__,
420420
static PyObject *
421421
PyZlib_objcompress(compobject *self, PyObject *args)
422422
{
423-
int err, inplen;
423+
int err;
424+
unsigned int inplen;
424425
Py_ssize_t length = DEFAULTALLOC;
425-
PyObject *RetVal;
426+
PyObject *RetVal = NULL;
426427
Py_buffer pinput;
427428
Byte *input;
428429
unsigned long start_total_out;
429430

430431
if (!PyArg_ParseTuple(args, "y*:compress", &pinput))
431432
return NULL;
433+
if (pinput.len > UINT_MAX) {
434+
PyErr_SetString(PyExc_OverflowError,
435+
"Size does not fit in an unsigned int");
436+
goto error_outer;
437+
}
432438
input = pinput.buf;
433439
inplen = pinput.len;
434440

435-
if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) {
436-
PyBuffer_Release(&pinput);
437-
return NULL;
438-
}
441+
if (!(RetVal = PyBytes_FromStringAndSize(NULL, length)))
442+
goto error_outer;
439443

440444
ENTER_ZLIB(self);
441445

@@ -484,6 +488,7 @@ PyZlib_objcompress(compobject *self, PyObject *args)
484488

485489
error:
486490
LEAVE_ZLIB(self);
491+
error_outer:
487492
PyBuffer_Release(&pinput);
488493
return RetVal;
489494
}
@@ -502,32 +507,35 @@ PyDoc_STRVAR(decomp_decompress__doc__,
502507
static PyObject *
503508
PyZlib_objdecompress(compobject *self, PyObject *args)
504509
{
505-
int err, inplen, max_length = 0;
510+
int err, max_length = 0;
511+
unsigned int inplen;
506512
Py_ssize_t old_length, length = DEFAULTALLOC;
507-
PyObject *RetVal;
513+
PyObject *RetVal = NULL;
508514
Py_buffer pinput;
509515
Byte *input;
510516
unsigned long start_total_out;
511517

512518
if (!PyArg_ParseTuple(args, "y*|i:decompress", &pinput,
513519
&max_length))
514520
return NULL;
521+
if (pinput.len > UINT_MAX) {
522+
PyErr_SetString(PyExc_OverflowError,
523+
"Size does not fit in an unsigned int");
524+
goto error_outer;
525+
}
515526
input = pinput.buf;
516527
inplen = pinput.len;
517528
if (max_length < 0) {
518-
PyBuffer_Release(&pinput);
519529
PyErr_SetString(PyExc_ValueError,
520530
"max_length must be greater than zero");
521-
return NULL;
531+
goto error_outer;
522532
}
523533

524534
/* limit amount of data allocated to max_length */
525535
if (max_length && length > max_length)
526536
length = max_length;
527-
if (!(RetVal = PyBytes_FromStringAndSize(NULL, length))) {
528-
PyBuffer_Release(&pinput);
529-
return NULL;
530-
}
537+
if (!(RetVal = PyBytes_FromStringAndSize(NULL, length)))
538+
goto error_outer;
531539

532540
ENTER_ZLIB(self);
533541

@@ -621,6 +629,7 @@ PyZlib_objdecompress(compobject *self, PyObject *args)
621629

622630
error:
623631
LEAVE_ZLIB(self);
632+
error_outer:
624633
PyBuffer_Release(&pinput);
625634
return RetVal;
626635
}

0 commit comments

Comments
 (0)