diff options
author | Guido van Rossum <guido@python.org> | 2007-02-26 21:23:50 +0000 |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2007-02-26 21:23:50 +0000 |
commit | a980f3d2ef986ceb1530d9daee120247419e9878 (patch) | |
tree | 7631080664f51947f83fa53d744d49660dbde272 /Python/compile.c | |
parent | 6df3663c941d5d31238292261a1e0aab0d858c86 (diff) | |
download | cpython-a980f3d2ef986ceb1530d9daee120247419e9878.tar.gz |
Two more patches by Tony Lownds (SF# 1607548).
(1)
Combines the code paths for MAKE_FUNCTION and MAKE_CLOSURE.
Fixes a crash where functions with closures and either annotations or
keyword-only arguments result in MAKE_CLOSURE, but only
MAKE_FUNCTION has the code to handle annotations or keyword-only
arguments.
Includes enough tests to trigger the bug.
(2)
Change peepholer to not bail in the presence of EXTENDED_ARG +
MAKE_FUNCTION.
Enforce the natural 16-bit limit of annotations in compile.c.
Also update Misc/NEWS with the "input = raw_input" change.
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)) |