Skip to content

Commit 750c3ef

Browse files
miss-islingtonfatihhcelikblurb-it[bot]picnixz
authored
[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 3ca1f2a) 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>
1 parent de34f6d commit 750c3ef

File tree

4 files changed

+11
-5
lines changed

4 files changed

+11
-5
lines changed

Doc/library/zoneinfo.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,9 @@ The ``ZoneInfo`` class has two alternate constructors:
206206

207207
Objects created via this constructor cannot be pickled (see `pickling`_).
208208

209+
:exc:`ValueError` is raised if the data read from *file_obj* is not a valid
210+
TZif file.
211+
209212
.. classmethod:: ZoneInfo.no_cache(key)
210213

211214
An alternate constructor that bypasses the constructor's cache. It is

Lib/test/test_zoneinfo/test_zoneinfo.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,8 @@ def test_bad_zones(self):
252252
bad_zones = [
253253
b"", # Empty file
254254
b"AAAA3" + b" " * 15, # Bad magic
255+
# Truncated V2 file (should not loop indefinitely)
256+
b"TZif2" + (b"\x00" * 39) + b"TZif2" + (b"\x00" * 39) + b"\n" + b"Part",
255257
]
256258

257259
for bad_zone in bad_zones:

Lib/zoneinfo/_common.py

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,11 +118,10 @@ def get_abbr(idx):
118118
c = fobj.read(1) # Should be \n
119119
assert c == b"\n", c
120120

121-
tz_bytes = b""
122-
while (c := fobj.read(1)) != b"\n":
123-
tz_bytes += c
124-
125-
tz_str = tz_bytes
121+
line = fobj.readline()
122+
if not line.endswith(b"\n"):
123+
raise ValueError("Invalid TZif file: unexpected end of file")
124+
tz_str = line.rstrip(b"\n")
126125
else:
127126
tz_str = None
128127

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`zoneinfo`: fix infinite loop in :meth:`ZoneInfo.from_file
2+
<zoneinfo.ZoneInfo.from_file>` when parsing a malformed TZif file. Patch by Fatih Celik.

0 commit comments

Comments
 (0)