summaryrefslogtreecommitdiffstats
path: root/Python
diff options
context:
space:
mode:
authorJeremy Hylton <jeremy@alum.mit.edu>2001-02-12 16:01:03 (GMT)
committerJeremy Hylton <jeremy@alum.mit.edu>2001-02-12 16:01:03 (GMT)
commitd7f393edae342b9d2fe657ce623a359f3190c890 (patch)
tree23dfd9a3117c58b135b9acbc5523f4c1ab282997 /Python
parentb258bedb138587a30e13bac378b5a00ea5e4c7bf (diff)
downloadcpython-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.
Diffstat (limited to 'Python')
-rw-r--r--Python/compile.c34
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;
}