Skip to content

Commit 3b06d68

Browse files
gh-146076: Fix crash when a ZoneInfo subclass is missing a _weak_cache (#146082)
1 parent d42a04c commit 3b06d68

File tree

3 files changed

+20
-0
lines changed

3 files changed

+20
-0
lines changed

Lib/test/test_zoneinfo/test_zoneinfo.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1595,6 +1595,18 @@ class ZI(self.klass):
15951595
"Unexpected instance of int in ZI weak cache for key 'America/Los_Angeles'"
15961596
)
15971597

1598+
def test_deleted_weak_cache(self):
1599+
class ZI(self.klass):
1600+
pass
1601+
delattr(ZI, '_weak_cache')
1602+
1603+
# These should not segfault
1604+
with self.assertRaises(AttributeError):
1605+
ZI("UTC")
1606+
1607+
with self.assertRaises(AttributeError):
1608+
ZI.clear_cache()
1609+
15981610
def test_inconsistent_weak_cache_setdefault(self):
15991611
class Cache:
16001612
def get(self, key, default=None):
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
:mod:`zoneinfo`: fix crashes when deleting ``_weak_cache`` from a
2+
:class:`zoneinfo.ZoneInfo` subclass.

Modules/_zoneinfo.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,9 @@ zoneinfo_ZoneInfo_impl(PyTypeObject *type, PyObject *key)
321321
}
322322

323323
PyObject *weak_cache = get_weak_cache(state, type);
324+
if (weak_cache == NULL) {
325+
return NULL;
326+
}
324327
instance = PyObject_CallMethod(weak_cache, "get", "O", key, Py_None);
325328
if (instance == NULL) {
326329
Py_DECREF(weak_cache);
@@ -505,6 +508,9 @@ zoneinfo_ZoneInfo_clear_cache_impl(PyTypeObject *type, PyTypeObject *cls,
505508
{
506509
zoneinfo_state *state = zoneinfo_get_state_by_cls(cls);
507510
PyObject *weak_cache = get_weak_cache(state, type);
511+
if (weak_cache == NULL) {
512+
return NULL;
513+
}
508514

509515
if (only_keys == NULL || only_keys == Py_None) {
510516
PyObject *rv = PyObject_CallMethod(weak_cache, "clear", NULL);

0 commit comments

Comments
 (0)