8000 bpo-43132: Fix incorrect handling of PyObject_RichCompareBool() in _z… · python/cpython@effaec0 · GitHub
[go: up one dir, main page]

Skip to content 8000

Commit effaec0

Browse files
authored
bpo-43132: Fix incorrect handling of PyObject_RichCompareBool() in _zoneinfo (GH-24450)
PyObject_RichCompareBool() returns -1 on error, but this case is not handled by the find_in_strong_cache() function. Any exception raised by PyObject_RichCompareBool() should be propagated.
1 parent 755c6e6 commit effaec0

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

Modules/_zoneinfo.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ is_leap_year(int year);
164164
static size_t
165165
_bisect(const int64_t value, const int64_t *arr, size_t size);
166166

167-
static void
167+
static int
168168
eject_from_strong_cache(const PyTypeObject *const type, PyObject *key);
169169
static void
170170
clear_strong_cache(const PyTypeObject *const type);
@@ -266,7 +266,7 @@ zoneinfo_new(PyTypeObject *type, PyObject *args, PyObject *kw)
266266
}
267267

268268
PyObject *instance = zone_from_strong_cache(type, key);
269-
if (instance != NULL) {
269+
if (instance != NULL || PyErr_Occurred()) {
270270
return instance;
271271
}
272272

@@ -429,7 +429,10 @@ zoneinfo_clear_cache(PyObject *cls, PyObject *args, PyObject *kwargs)
429429

430430
while ((item = PyIter_Next(iter))) {
431431
// Remove from strong cache
432-
eject_from_strong_cache(type, item);
432+
if (eject_from_strong_cache(type, item) < 0) {
433+
Py_DECREF(item);
434+
break;
435+
}
433436

434437
// Remove from weak cache
435438
PyObject *tmp = PyObject_CallMethodObjArgs(weak_cache, pop, item,
@@ -2342,7 +2345,11 @@ find_in_strong_cache(const StrongCacheNode *const root, PyObject *const key)
23422345
{
23432346
const StrongCacheNode *node = root;
23442347
while (node != NULL) {
2345-
if (PyObject_RichCompareBool(key, node->key, Py_EQ)) {
2348+
int rv = PyObject_RichCompareBool(key, node->key, Py_EQ);
2349+
if (rv < 0) {
2350+
return NULL;
2351+
}
2352+
if (rv) {
23462353
return (StrongCacheNode *)node;
23472354
}
23482355

@@ -2356,11 +2363,11 @@ find_in_strong_cache(const StrongCacheNode *const root, PyObject *const key)
23562363
*
23572364
* This function is used to enable the per-key functionality in clear_cache.
23582365
*/
2359-
static void
2366+
static int
23602367
eject_from_strong_cache(const PyTypeObject *const type, PyObject *key)
23612368
{
23622369
if (type != &PyZoneInfo_ZoneInfoType) {
2363-
return;
2370+
return 0;
23642371
}
23652372

23662373
StrongCacheNode *node = find_in_strong_cache(ZONEINFO_STRONG_CACHE, key);
@@ -2369,6 +2376,10 @@ eject_from_strong_cache(const PyTypeObject *const type, PyObject *key)
23692376

23702377
strong_cache_node_free(node);
23712378
}
2379+
else if (PyErr_Occurred()) {
2380+
return -1;
2381+
}
2382+
return 0;
23722383
}
23732384

23742385
/* Moves a node to the front of the LRU cache.

0 commit comments

Comments
 (0)
0