Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit d7f393e

Browse files
committed
In symtable_update_free_vars() do not modify the dictionary while
iterating over it using PyDict_Next(). This bug fix brought to you by the letters b, c, d, g, h, ... and the reporter Ping.
1 parent b258bed commit d7f393e

1 file changed

Lines changed: 27 additions & 7 deletions

File tree

Python/compile.c

Lines changed: 27 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4205,8 +4205,8 @@ PySymtable_Free(struct symtable *st)
42054205
static int
42064206
symtable_update_free_vars(struct symtable *st)
42074207
{
4208-
PyObject *o, *name;
4209-
int i, def;
4208+
int i, j, def;
4209+
PyObject *o, *name, *list = NULL;
42104210
PySymtableEntryObject *child, *ste = st->st_cur;
42114211

42124212
if (ste->ste_type == TYPE_CLASS)
@@ -4216,25 +4216,45 @@ symtable_update_free_vars(struct symtable *st)
42164216
for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) {
42174217
int pos = 0;
42184218

4219+
if (list)
4220+
PyList_SetSlice(list, 0,
4221+
((PyVarObject*)list)->ob_size, 0);
42194222
child = (PySymtableEntryObject *)\
42204223
PyList_GET_ITEM(ste->ste_children, i);
42214224
while (PyDict_Next(child->ste_symbols, &pos, &name, &o)) {
42224225
int v = PyInt_AS_LONG(o);
42234226
if (!(is_free(v)))
42244227
continue; /* avoids indentation */
4228+
if (list == NULL) {
4229+
list = PyList_New(0);
4230+
if (list == NULL)
4231+
return -1;
4232+
}
42254233
ste->ste_child_free = 1;
4234+
if (PyList_Append(list, name) < 0) {
4235+
Py_DECREF(list);
4236+
return -1;
4237+
}
4238+
}
4239+
for (j = 0; list && j < PyList_GET_SIZE(list); j++) {
4240+
name = PyList_GET_ITEM(list, j);
42264241
if (ste->ste_nested) {
42274242
if (symtable_add_def_o(st, ste->ste_symbols,
4228-
name, def) < 0)
4229-
return -1;
4243+
name, def) < 0) {
4244+
Py_DECREF(list);
4245+
return -1;
4246+
}
42304247
} else {
42314248
if (symtable_check_global(st, child->ste_id,
4232-
name) < 0)
4233-
return -1;
4249+
name) < 0) {
4250+
Py_DECREF(list);
4251+
return -1;
4252+
}
42344253
}
42354254
}
42364255
}
4237-
4256+
4257+
Py_XDECREF(list);
42384258
return 0;
42394259
}
42404260

0 commit comments

Comments
 (0)