From eb863e122c031247e5f68a97b8ad6714877fbc36 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Thu, 29 Aug 2019 22:17:08 +1000 Subject: [PATCH 1/3] bpo-37947: Avoid double-decrement in symtable recursion counting --- Python/symtable.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Python/symtable.c b/Python/symtable.c index 2795e0f1115b8d..5903e0b6a5c548 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -1501,16 +1501,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 From b4a341ee5b997662b1899edccfb354a4e6350ec5 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Thu, 29 Aug 2019 22:50:57 +1000 Subject: [PATCH 2/3] Ensure the symtable recursion accounting balances --- Python/symtable.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/Python/symtable.c b/Python/symtable.c index 5903e0b6a5c548..ee7502de14b657 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,10 @@ 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 +332,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; From 6e83dc2219473ce5f8a86ea1a2e871ee517463a2 Mon Sep 17 00:00:00 2001 From: Nick Coghlan Date: Thu, 29 Aug 2019 22:53:03 +1000 Subject: [PATCH 3/3] Remove spurious line --- Python/symtable.c | 1 - 1 file changed, 1 deletion(-) diff --git a/Python/symtable.c b/Python/symtable.c index ee7502de14b657..f2453db69dd7dd 100644 --- a/Python/symtable.c +++ b/Python/symtable.c @@ -285,7 +285,6 @@ PySymtable_BuildObject(mod_ty mod, PyObject *filename, PyFutureFeatures *future) return NULL; } /* Be careful here to prevent overflow. */ - 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;