Mercurial > cpython-lru_cache-weakref
diff Python/compile.c @ 16571:2c6417ef4628 legacy-trunk
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.
| author | Jeremy Hylton <jeremy@alum.mit.edu> |
|---|---|
| date | Mon, 12 Feb 2001 16:01:03 +0000 |
| parents | 8236f3e7585e |
| children | 79568c0d3e77 |
line wrap: on
line diff
--- a/Python/compile.c Mon Feb 12 15:30:22 2001 +0000 +++ b/Python/compile.c Mon Feb 12 16:01:03 2001 +0000 @@ -4205,8 +4205,8 @@ static int symtable_update_free_vars(struct symtable *st) { - PyObject *o, *name; - int i, def; + int i, j, def; + PyObject *o, *name, *list = NULL; PySymtableEntryObject *child, *ste = st->st_cur; if (ste->ste_type == TYPE_CLASS) @@ -4216,25 +4216,45 @@ for (i = 0; i < PyList_GET_SIZE(ste->ste_children); ++i) { int pos = 0; + if (list) + PyList_SetSlice(list, 0, + ((PyVarObject*)list)->ob_size, 0); child = (PySymtableEntryObject *)\ PyList_GET_ITEM(ste->ste_children, i); while (PyDict_Next(child->ste_symbols, &pos, &name, &o)) { int v = PyInt_AS_LONG(o); if (!(is_free(v))) continue; /* avoids indentation */ + if (list == NULL) { + list = PyList_New(0); + if (list == NULL) + return -1; + } ste->ste_child_free = 1; + if (PyList_Append(list, name) < 0) { + Py_DECREF(list); + return -1; + } + } + for (j = 0; list && j < PyList_GET_SIZE(list); j++) { + name = PyList_GET_ITEM(list, j); if (ste->ste_nested) { if (symtable_add_def_o(st, ste->ste_symbols, - name, def) < 0) - return -1; + name, def) < 0) { + Py_DECREF(list); + return -1; + } } else { if (symtable_check_global(st, child->ste_id, - name) < 0) - return -1; + name) < 0) { + Py_DECREF(list); + return -1; + } } } } - + + Py_XDECREF(list); return 0; }
