From 93d7df06e0ef080358fb61a74461bd7338682cd9 Mon Sep 17 00:00:00 2001 From: Serhiy Storchaka Date: Mon, 18 May 2026 13:04:00 +0300 Subject: [PATCH] gh-149945: Fix potential OOM for gzip with large header Do not read the whole filename and comment to memory for calculating the CRC. --- Lib/gzip.py | 50 ++++++++++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 20 deletions(-) diff --git a/Lib/gzip.py b/Lib/gzip.py index a89ebf806c8572..1e05f43c0c9e24 100644 --- a/Lib/gzip.py +++ b/Lib/gzip.py @@ -484,14 +484,22 @@ def _read_exact(fp, n): return data -def _read_until_null(fp, append_to): +def _read_until_null(fp, crc=None): '''Read until the first encountered null byte in fp. - Append to given byte array object''' - while True: - s = fp.read(1) - append_to += s - if not s or s == b'\000': - break + If crc is not None, update and return the CRC. + ''' + if crc is None: + while True: + s = fp.read(1) + if not s or s == b'\000': + break + else: + while True: + s = fp.read(1) + crc = zlib.crc32(s, crc) + if not s or s == b'\000': + break + return crc def _read_gzip_header(fp): @@ -517,30 +525,32 @@ def _read_gzip_header(fp): return last_mtime if flag == FNAME: # Read and discard a null-terminated string containing the filename - while True: - s = fp.read(1) - if not s or s==b'\000': - break + _read_until_null(fp) return last_mtime # Processing for more complex flags. Save header parts for FHCRC checking. - header = bytearray(magic + base_header) + if flag & FHCRC: + crc = zlib.crc32(magic + base_header) + else: + crc = None if flag & FEXTRA: extra_len_bytes = _read_exact(fp, 2) extra_len, = struct.unpack("