diff options
Diffstat (limited to 'Python/compile.c')
-rw-r--r-- | Python/compile.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/Python/compile.c b/Python/compile.c index ed0bdcf92a..7f0fc503bb 100644 --- a/Python/compile.c +++ b/Python/compile.c @@ -836,6 +836,8 @@ opcode_stack_effect(int opcode, int oparg) return -NARGS(oparg)-2; case MAKE_FUNCTION: return -NARGS(oparg) - ((oparg >> 16) & 0xffff); + case MAKE_CLOSURE: + return -1 - NARGS(oparg) - ((oparg >> 16) & 0xffff); #undef NARGS case BUILD_SLICE: if (oparg == 3) @@ -843,8 +845,6 @@ opcode_stack_effect(int opcode, int oparg) else return -1; - case MAKE_CLOSURE: - return -oparg; case LOAD_CLOSURE: return 1; case LOAD_DEREF: @@ -1367,8 +1367,12 @@ static int compiler_visit_annotations(struct compiler *c, arguments_ty args, expr_ty returns) { - /* push arg annotations and a list of the argument names. return the # - of items pushed. this is out-of-order wrt the source code. */ + /* Push arg annotations and a list of the argument names. Return the # + of items pushed. The expressions are evaluated out-of-order wrt the + source code. + + More than 2^16-1 annotations is a SyntaxError. Returns -1 on error. + */ static identifier return_str; PyObject *names; int len; @@ -1399,6 +1403,12 @@ compiler_visit_annotations(struct compiler *c, arguments_ty args, } len = PyList_GET_SIZE(names); + if (len > 65534) { + /* len must fit in 16 bits, and len is incremented below */ + PyErr_SetString(PyExc_SyntaxError, + "too many annotations"); + goto error; + } if (len) { /* convert names to a tuple and place on stack */ PyObject *elt; @@ -1449,6 +1459,9 @@ compiler_function(struct compiler *c, stmt_ty s) if (args->defaults) VISIT_SEQ(c, expr, args->defaults); num_annotations = compiler_visit_annotations(c, args, returns); + if (num_annotations < 0) + return 0; + assert((num_annotations & 0xFFFF) == num_annotations); if (!compiler_enter_scope(c, s->v.FunctionDef.name, (void *)s, s->lineno)) |