[3.13] gh-143241: Fix infinite loop in zoneinfo._common.load_data (GH-143243) (#143252)

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 3ca1f2a370)

Co-authored-by: Fatih Çelik <fcelik.ft@gmail.com>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Bénédikt Tran <10796600+picnixz@users.noreply.github.com>
This commit is contained in:
Miss Islington (bot) 2025-12-28 16:11:32 +01:00 committed by GitHub
parent de34f6d404
commit 750c3efe82
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 11 additions and 5 deletions

View file

@ -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

View file

@ -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:

View file

@ -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

View file

@ -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.