summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNick Coghlan <ncoghlan@gmail.com>2019-08-29 13:26:53 (GMT)
committerGitHub <noreply@github.com>2019-08-29 13:26:53 (GMT)
commit06145230c833c3db5dab8858e11bcd550a37c57f (patch)
treed5b2743b4279402eb1f7a181ee911549d9172953
parent2c5fb1711818926862d0d7b2e5effcaa5a5eb002 (diff)
downloadcpython-06145230c833c3db5dab8858e11bcd550a37c57f.zip
cpython-06145230c833c3db5dab8858e11bcd550a37c57f.tar.gz
cpython-06145230c833c3db5dab8858e11bcd550a37c57f.tar.bz2
bpo-37947: Avoid double-decrement in symtable recursion counting (GH-15593)
With `symtable_visit_expr` now correctly adjusting the recursion depth for named expressions, `symtable_handle_namedexpr` should be leaving it alone. Also adds a new check to `PySymtable_BuildObject` that raises `SystemError` if a successful first symbol analysis pass fails to keep the stack depth accounting clean.
-rw-r--r--Python/symtable.c18
1 files changed, 14 insertions, 4 deletions
diff --git a/Python/symtable.c b/Python/symtable.c
index 2795e0f..f2453db 100644
--- a/Python/symtable.c
+++ b/Python/symtable.c
@@ -266,6 +266,7 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future)
int i;
PyThreadState *tstate;
int recursion_limit = Py_GetRecursionLimit();
+ int starting_recursion_depth;
if (st == NULL)
return NULL;
@@ -284,8 +285,9 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future)
return NULL;
}
/* Be careful here to prevent overflow. */
- st->recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
+ starting_recursion_depth = (tstate->recursion_depth < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
tstate->recursion_depth * COMPILER_STACK_FRAME_SCALE : tstate->recursion_depth;
+ st->recursion_depth = starting_recursion_depth;
st->recursion_limit = (recursion_limit < INT_MAX / COMPILER_STACK_FRAME_SCALE) ?
recursion_limit * COMPILER_STACK_FRAME_SCALE : recursion_limit;
@@ -329,6 +331,14 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future)
PySymtable_Free(st);
return NULL;
}
+ /* Check that the recursion depth counting balanced correctly */
+ if (st->recursion_depth != starting_recursion_depth) {
+ PyErr_Format(PyExc_SystemError,
+ "symtable analysis recursion depth mismatch (before=%d, after=%d)",
+ starting_recursion_depth, st->recursion_depth);
+ PySymtable_Free(st);
+ return NULL;
+ }
/* Make the second symbol analysis pass */
if (symtable_analyze(st))
return st;
@@ -1501,16 +1511,16 @@ symtable_handle_namedexpr(struct symtable *st, expr_ty e)
PyErr_SyntaxLocationObject(st->st_filename,
e->lineno,
e->col_offset);
- VISIT_QUIT(st, 0);
+ return 0;
}
if (st->st_cur->ste_comprehension) {
/* Inside a comprehension body, so find the right target scope */
if (!symtable_extend_namedexpr_scope(st, e->v.NamedExpr.target))
- VISIT_QUIT(st, 0);
+ return 0;
}
VISIT(st, expr, e->v.NamedExpr.value);
VISIT(st, expr, e->v.NamedExpr.target);
- VISIT_QUIT(st, 1);
+ return 1;
}
static int