with self.assertRaises(ValueError):
self.klass.from_file(zf)
+ def test_invalid_transition_index(self):
+ STD = ZoneOffset("STD", ZERO)
+ DST = ZoneOffset("DST", ONE_H, ONE_H)
+
+ zf = self.construct_zone([
+ ZoneTransition(datetime(2026, 3, 1, 2), STD, DST),
+ ZoneTransition(datetime(2026, 11, 1, 2), DST, STD),
+ ], after="", version=1)
+
+ data = bytearray(zf.read())
+ timecnt = struct.unpack_from(">l", data, 32)[0]
+ idx_offset = 44 + timecnt * 4
+ data[idx_offset + 1] = 2 # typecnt is 2, so index 2 is OOB
+ f = io.BytesIO(bytes(data))
+
+ with self.assertRaises(ValueError):
+ self.klass.from_file(f)
+
+ def test_transition_lookahead_out_of_bounds(self):
+ STD = ZoneOffset("STD", ZERO)
+ DST = ZoneOffset("DST", ONE_H, ONE_H)
+ EXT = ZoneOffset("EXT", ONE_H)
+
+ zf = self.construct_zone([
+ ZoneTransition(datetime(2026, 3, 1), STD, DST),
+ ZoneTransition(datetime(2026, 6, 1), DST, EXT),
+ ZoneTransition(datetime(2026, 9, 1), EXT, DST),
+ ], after="")
+
+ zi = self.klass.from_file(zf)
+ self.assertIsNotNone(zi)
+
def test_zone_very_large_timestamp(self):
"""Test when a transition is in the far past or future.
}
trans_idx[i] = (size_t)cur_trans_idx;
- if (trans_idx[i] > self->num_ttinfos) {
+ if (trans_idx[i] >= self->num_ttinfos) {
PyErr_Format(
PyExc_ValueError,
"Invalid transition index found while reading TZif: %zd",
dstoff = utcoff - utcoffs[comp_idx];
}
- if (!dstoff && idx < (num_ttinfos - 1)) {
+ if (!dstoff && idx < (num_ttinfos - 1) && i + 1 < num_transitions) {
comp_idx = trans_idx[i + 1];
// If the following transition is also DST and we couldn't find