diff options
author | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-02-12 16:01:03 (GMT) |
---|---|---|
committer | Jeremy Hylton <jeremy@alum.mit.edu> | 2001-02-12 16:01:03 (GMT) |
commit | d7f393edae342b9d2fe657ce623a359f3190c890 (patch) | |
tree | 23dfd9a3117c58b135b9acbc5523f4c1ab282997 | |
parent | b258bedb138587a30e13bac378b5a00ea5e4c7bf (diff) | |
download | cpython-d7f393edae342b9d2fe657ce623a359f3190c890.zip cpython-d7f393edae342b9d2fe657ce623a359f3190c890.tar.gz cpython-d7f393edae342b9d2fe657ce623a359f3190c890.tar.bz2 |
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.
-rw-r--r-- | Python/compile.c | 34 |
1 files changed, 27 insertions, 7 deletions
diff --git a/Python/compile.c b/Python/compile.c index 8370e09..916c4a6 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -4205,8 +4205,8 @@ PySymtable_Free(struct symtable *st) 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 @@ symtable_update_free_vars(struct symtable *st) 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; } |