Skip to content

Commit 50e4143

Browse files
[3.11] Check the result of PySet_Contains() for error in Python/symtable.c (GH-109146) (GH-109158)
(cherry picked from commit 87a7faf)
1 parent 6b2f44e commit 50e4143

File tree

1 file changed

+40
-12
lines changed

1 file changed

+40
-12
lines changed

Python/symtable.c

Lines changed: 40 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -502,6 +502,7 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
502502
PyObject *bound, PyObject *local, PyObject *free,
503503
PyObject *global)
504504
{
505+
int contains;
505506
if (flags & DEF_GLOBAL) {
506507
if (flags & DEF_NONLOCAL) {
507508
PyErr_Format(PyExc_SyntaxError,
@@ -522,7 +523,11 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
522523
"nonlocal declaration not allowed at module level");
523524
return error_at_directive(ste, name);
524525
}
525-
if (!PySet_Contains(bound, name)) {
526+
contains = PySet_Contains(bound, name);
527+
if (contains < 0) {
528+
return 0;
529+
}
530+
if (!contains) {
526531
PyErr_Format(PyExc_SyntaxError,
527532
"no binding for nonlocal '%U' found",
528533
name);
@@ -546,17 +551,29 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
546551
Note that having a non-NULL bound implies that the block
547552
is nested.
548553
*/
549-
if (bound && PySet_Contains(bound, name)) {
550-
SET_SCOPE(scopes, name, FREE);
551-
ste->ste_free = 1;
552-
return PySet_Add(free, name) >= 0;
554+
if (bound) {
555+
contains = PySet_Contains(bound, name);
556+
if (contains < 0) {
557+
return 0;
558+
}
559+
if (contains) {
560+
SET_SCOPE(scopes, name, FREE);
561+
ste->ste_free = 1;
562+
return PySet_Add(free, name) >= 0;
563+
}
553564
}
554565
/* If a parent has a global statement, then call it global
555566
explicit? It could also be global implicit.
556567
*/
557-
if (global && PySet_Contains(global, name)) {
558-
SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
559-
return 1;
568+
if (global) {
569+
contains = PySet_Contains(global, name);
570+
if (contains < 0) {
571+
return 0;
572+
}
573+
if (contains) {
574+
SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
575+
return 1;
576+
}
560577
}
561578
if (ste->ste_nested)
562579
ste->ste_free = 1;
@@ -590,8 +607,13 @@ analyze_cells(PyObject *scopes, PyObject *free)
590607
scope = PyLong_AS_LONG(v);
591608
if (scope != LOCAL)
592609
continue;
593-
if (!PySet_Contains(free, name))
610+
int contains = PySet_Contains(free, name);
611+
if (contains < 0) {
612+
goto error;
613+
}
614+
if (!contains) {
594615
continue;
616+
}
595617
/* Replace LOCAL with CELL for this name, and remove
596618
from free. It is safe to replace the value of name
597619
in the dict, because it will not cause a resize.
@@ -691,9 +713,15 @@ update_symbols(PyObject *symbols, PyObject *scopes,
691713
goto error;
692714
}
693715
/* Handle global symbol */
694-
if (bound && !PySet_Contains(bound, name)) {
695-
Py_DECREF(name);
696-
continue; /* it's a global */
716+
if (bound) {
717+
int contains = PySet_Contains(bound, name);
718+
if (contains < 0) {
719+
goto error;
720+
}
721+
if (!contains) {
722+
Py_DECREF(name);
723+
continue; /* it's a global */
724+
}
697725
}
698726
/* Propagate new free symbol up the lexical stack */
699727
if (PyDict_SetItem(symbols, name, v_free) < 0) {

0 commit comments

Comments
 (0)