Skip to content

Commit ec6dfcf

Browse files
committed
Issue #16411: Fix a bug where zlib.decompressobj().flush() might try to access previously-freed memory.
Patch by Serhiy Storchaka.
2 parents dd1253a + 7ee9555 commit ec6dfcf

3 files changed

Lines changed: 17 additions & 0 deletions

File tree

Lib/test/test_zlib.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,6 +513,18 @@ def test_decompress_unused_data(self):
513513
self.assertEqual(dco.unconsumed_tail, b'')
514514
self.assertEqual(dco.unused_data, remainder)
515515

516+
def test_flush_with_freed_input(self):
517+
# Issue #16411: decompressor accesses input to last decompress() call
518+
# in flush(), even if this object has been freed in the meanwhile.
519+
input1 = b'abcdefghijklmnopqrstuvwxyz'
520+
input2 = b'QWERTYUIOPASDFGHJKLZXCVBNM'
521+
data = zlib.compress(input1)
522+
dco = zlib.decompressobj()
523+
dco.decompress(data, 1)
524+
del data
525+
data = zlib.compress(input2)
526+
self.assertEqual(dco.flush(), input1[1:])
527+
516528
if hasattr(zlib.compressobj(), "copy"):
517529
def test_compresscopy(self):
518530
# Test copying a compression object

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,9 @@ Core and Builtins
8080
Library
8181
-------
8282

83+
- Issue #16411: Fix a bug where zlib.decompressobj().flush() might try to access
84+
previously-freed memory. Patch by Serhiy Storchaka.
85+
8386
- Issue #16357: fix calling accept() on a SSLSocket created through
8487
SSLContext.wrap_socket(). Original patch by Jeff McNeil.
8588

Modules/zlibmodule.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -975,6 +975,8 @@ PyZlib_unflush(compobject *self, PyObject *args)
975975
ENTER_ZLIB(self);
976976

977977
start_total_out = self->zst.total_out;
978+
self->zst.avail_in = PyBytes_GET_SIZE(self->unconsumed_tail);
979+
self->zst.next_in = (Byte *)PyBytes_AS_STRING(self->unconsumed_tail);
978980
self->zst.avail_out = length;
979981
self->zst.next_out = (Byte *)PyBytes_AS_STRING(retval);
980982

0 commit comments

Comments
 (0)