Skip to content

Commit 87a7faf

Browse files
Check the result of PySet_Contains() for error in Python/symtable.c (GH-109146)
1 parent 501f2dc commit 87a7faf

File tree

1 file changed

+57
-15
lines changed

1 file changed

+57
-15
lines changed

Python/symtable.c

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -523,6 +523,7 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
523523
PyObject *bound, PyObject *local, PyObject *free,
524524
PyObject *global, PyObject *type_params, PySTEntryObject *class_entry)
525525
{
526+
int contains;
526527
if (flags & DEF_GLOBAL) {
527528
if (flags & DEF_NONLOCAL) {
528529
PyErr_Format(PyExc_SyntaxError,
@@ -543,14 +544,22 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
543544
"nonlocal declaration not allowed at module level");
544545
return error_at_directive(ste, name);
545546
}
546-
if (!PySet_Contains(bound, name)) {
547+
contains = PySet_Contains(bound, name);
548+
if (contains < 0) {
549+
return 0;
550+
}
551+
if (!contains) {
547552
PyErr_Format(PyExc_SyntaxError,
548553
"no binding for nonlocal '%U' found",
549554
name);
550555

551556
return error_at_directive(ste, name);
552557
}
553-
if (PySet_Contains(type_params, name)) {
558+
contains = PySet_Contains(type_params, name);
559+
if (contains < 0) {
560+
return 0;
561+
}
562+
if (contains) {
554563
PyErr_Format(PyExc_SyntaxError,
555564
"nonlocal binding not allowed for type parameter '%U'",
556565
name);
@@ -599,17 +608,29 @@ analyze_name(PySTEntryObject *ste, PyObject *scopes, PyObject *name, long flags,
599608
Note that having a non-NULL bound implies that the block
600609
is nested.
601610
*/
602-
if (bound && PySet_Contains(bound, name)) {
603-
SET_SCOPE(scopes, name, FREE);
604-
ste->ste_free = 1;
605-
return PySet_Add(free, name) >= 0;
611+
if (bound) {
612+
contains = PySet_Contains(bound, name);
613+
if (contains < 0) {
614+
return 0;
615+
}
616+
if (contains) {
617+
SET_SCOPE(scopes, name, FREE);
618+
ste->ste_free = 1;
619+
return PySet_Add(free, name) >= 0;
620+
}
606621
}
607622
/* If a parent has a global statement, then call it global
608623
explicit? It could also be global implicit.
609624
*/
610-
if (global && PySet_Contains(global, name)) {
611-
SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
612-
return 1;
625+
if (global) {
626+
contains = PySet_Contains(global, name);
627+
if (contains < 0) {
628+
return 0;
629+
}
630+
if (contains) {
631+
SET_SCOPE(scopes, name, GLOBAL_IMPLICIT);
632+
return 1;
633+
}
613634
}
614635
if (ste->ste_nested)
615636
ste->ste_free = 1;
@@ -712,8 +733,19 @@ analyze_cells(PyObject *scopes, PyObject *free, PyObject *inlined_cells)
712733
scope = PyLong_AS_LONG(v);
713734
if (scope != LOCAL)
714735
continue;
715-
if (!PySet_Contains(free, name) && !PySet_Contains(inlined_cells, name))
716-
continue;
736+
int contains = PySet_Contains(free, name);
737+
if (contains < 0) {
738+
goto error;
739+
}
740+
if (!contains) {
741+
contains = PySet_Contains(inlined_cells, name);
742+
if (contains < 0) {
743+
goto error;
744+
}
745+
if (!contains) {
746+
continue;
747+
}
748+
}
717749
/* Replace LOCAL with CELL for this name, and remove
718750
from free. It is safe to replace the value of name
719751
in the dict, because it will not cause a resize.
@@ -764,7 +796,11 @@ update_symbols(PyObject *symbols, PyObject *scopes,
764796
long scope, flags;
765797
assert(PyLong_Check(v));
766798
flags = PyLong_AS_LONG(v);
767-
if (PySet_Contains(inlined_cells, name)) {
799+
int contains = PySet_Contains(inlined_cells, name);
800+
if (contains < 0) {
801+
return 0;
802+
}
803+
if (contains) {
768804
flags |= DEF_COMP_CELL;
769805
}
770806
v_scope = PyDict_GetItemWithError(scopes, name);
@@ -822,9 +858,15 @@ update_symbols(PyObject *symbols, PyObject *scopes,
822858
goto error;
823859
}
824860
/* Handle global symbol */
825-
if (bound && !PySet_Contains(bound, name)) {
826-
Py_DECREF(name);
827-
continue; /* it's a global */
861+
if (bound) {
862+
int contains = PySet_Contains(bound, name);
863+
if (contains < 0) {
864+
goto error;
865+
}
866+
if (!contains) {
867+
Py_DECREF(name);
868+
continue; /* it's a global */
869+
}
828870
}
829871
/* Propagate new free symbol up the lexical stack */
830872
if (PyDict_SetItem(symbols, name, v_free) < 0) {

0 commit comments

Comments
 (0)