https://github.com/python/cpython/commit/4c3e2114b5887592612baa14f09988867234dbe6 commit: 4c3e2114b5887592612baa14f09988867234dbe6 branch: 3.14 author: Miss Islington (bot) <[email protected]> committer: picnixz <[email protected]> date: 2025-12-28T15:14:04Z summary:
[3.14] gh-143241: Fix infinite loop in `zoneinfo._common.load_data` (GH-143243) (#143251) gh-143241: Fix infinite loop in `zoneinfo._common.load_data` (GH-143243) Correctly reject truncated TZif files in `ZoneInfo.from_file`. --------- (cherry picked from commit 3ca1f2a370e44874d0dc8c82a01465e0171bec5c) Co-authored-by: Fatih Çelik <[email protected]> Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com> Co-authored-by: Bénédikt Tran <[email protected]> files: A Misc/NEWS.d/next/Library/2025-12-28-13-49-06.gh-issue-143241.5H4b8d.rst M Doc/library/zoneinfo.rst M Lib/test/test_zoneinfo/test_zoneinfo.py M Lib/zoneinfo/_common.py diff --git a/Doc/library/zoneinfo.rst b/Doc/library/zoneinfo.rst index d95260896f75e1..efd28b31ef2a98 100644 --- a/Doc/library/zoneinfo.rst +++ b/Doc/library/zoneinfo.rst @@ -206,6 +206,9 @@ The ``ZoneInfo`` class has two alternate constructors: Objects created via this constructor cannot be pickled (see `pickling`_). + :exc:`ValueError` is raised if the data read from *file_obj* is not a valid + TZif file. + .. classmethod:: ZoneInfo.no_cache(key) An alternate constructor that bypasses the constructor's cache. It is diff --git a/Lib/test/test_zoneinfo/test_zoneinfo.py b/Lib/test/test_zoneinfo/test_zoneinfo.py index df7f0d82a2eac9..88d79b258cdf7a 100644 --- a/Lib/test/test_zoneinfo/test_zoneinfo.py +++ b/Lib/test/test_zoneinfo/test_zoneinfo.py @@ -252,6 +252,8 @@ def test_bad_zones(self): bad_zones = [ b"", # Empty file b"AAAA3" + b" " * 15, # Bad magic + # Truncated V2 file (should not loop indefinitely) + b"TZif2" + (b"\x00" * 39) + b"TZif2" + (b"\x00" * 39) + b"\n" + b"Part", ] for bad_zone in bad_zones: diff --git a/Lib/zoneinfo/_common.py b/Lib/zoneinfo/_common.py index 03cc42149f9b74..59f3f0ce853f74 100644 --- a/Lib/zoneinfo/_common.py +++ b/Lib/zoneinfo/_common.py @@ -118,11 +118,10 @@ def get_abbr(idx): c = fobj.read(1) # Should be \n assert c == b"\n", c - tz_bytes = b"" - while (c := fobj.read(1)) != b"\n": - tz_bytes += c - - tz_str = tz_bytes + line = fobj.readline() + if not line.endswith(b"\n"): + raise ValueError("Invalid TZif file: unexpected end of file") + tz_str = line.rstrip(b"\n") else: tz_str = None diff --git a/Misc/NEWS.d/next/Library/2025-12-28-13-49-06.gh-issue-143241.5H4b8d.rst b/Misc/NEWS.d/next/Library/2025-12-28-13-49-06.gh-issue-143241.5H4b8d.rst new file mode 100644 index 00000000000000..7170a06015ee7c --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-12-28-13-49-06.gh-issue-143241.5H4b8d.rst @@ -0,0 +1,2 @@ +:mod:`zoneinfo`: fix infinite loop in :meth:`ZoneInfo.from_file +<zoneinfo.ZoneInfo.from_file>` when parsing a malformed TZif file. Patch by Fatih Celik. _______________________________________________ Python-checkins mailing list -- [email protected] To unsubscribe send an email to [email protected] https://mail.python.org/mailman3//lists/python-checkins.python.org Member address: [email protected]
