Skip to content

Commit b764373

Browse files
Fix two heap-buffer-overflows in zoneinfo
1 parent 706fd4e commit b764373

7 files changed

Lines changed: 18 additions & 3 deletions

File tree

.gitattributes

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
*.zip binary
2020

2121
# Specific binary files
22+
Lib/test/test_zoneinfo/data/tzif_* binary
2223
PC/classicAppCompat.* binary
2324

2425
# Text files that should not be subject to eol conversion
288 Bytes
Binary file not shown.
289 Bytes
Binary file not shown.

Lib/test/test_zoneinfo/test_zoneinfo.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -741,6 +741,16 @@ def test_empty_zone(self):
741741
with self.assertRaises(ValueError):
742742
self.klass.from_file(zf)
743743

744+
def test_invalid_transition_index(self):
745+
with open(DATA_DIR / "tzif_invalid_trans_idx", "rb") as f:
746+
with self.assertRaises(ValueError):
747+
self.klass.from_file(f)
748+
749+
def test_transition_lookahead_out_of_bounds(self):
750+
with open(DATA_DIR / "tzif_invalid_lookahead", "rb") as f:
751+
zi = self.klass.from_file(f)
752+
self.assertIsNotNone(zi)
753+
744754
def test_zone_very_large_timestamp(self):
745755
"""Test when a transition is in the far past or future.
746756

Lib/zoneinfo/_common.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,10 @@ def load_data(fobj):
7171
trans_list_utc = ()
7272
trans_idx = ()
7373

74+
for idx in trans_idx:
75+
if idx >= typecnt:
76+
raise ValueError(f"Invalid transition index found while reading TZif: {idx}")
77+
7478
# Read the ttinfo struct, (utoff, isdst, abbrind)
7579
if typecnt:
7680
utcoff, isdst, abbrind = zip(

Lib/zoneinfo/_zoneinfo.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ def _utcoff_to_dstoff(trans_idx, utcoffsets, isdsts):
338338
if not isdsts[comp_idx]:
339339
dstoff = utcoff - utcoffsets[comp_idx]
340340

341-
if not dstoff and idx < (typecnt - 1):
341+
if not dstoff and idx < (typecnt - 1) and i + 1 < len(trans_idx):
342342
comp_idx = trans_idx[i + 1]
343343

344344
# If the following transition is also DST and we couldn't

Modules/_zoneinfo.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,7 +1065,7 @@ load_data(zoneinfo_state *state, PyZoneInfo_ZoneInfo *self, PyObject *file_obj)
10651065
}
10661066

10671067
trans_idx[i] = (size_t)cur_trans_idx;
1068-
if (trans_idx[i] > self->num_ttinfos) {
1068+
if (trans_idx[i] >= self->num_ttinfos) {
10691069
PyErr_Format(
10701070
PyExc_ValueError,
10711071
"Invalid transition index found while reading TZif: %zd",
@@ -2063,7 +2063,7 @@ utcoff_to_dstoff(size_t *trans_idx, long *utcoffs, long *dstoffs,
20632063
dstoff = utcoff - utcoffs[comp_idx];
20642064
}
20652065

2066-
if (!dstoff && idx < (num_ttinfos - 1)) {
2066+
if (!dstoff && idx < (num_ttinfos - 1) && i + 1 < num_transitions) {
20672067
comp_idx = trans_idx[i + 1];
20682068

20692069
// If the following transition is also DST and we couldn't find

0 commit comments

Comments
 (0)