diff options
author | Guido van Rossum <guido@python.org> | 2007-02-26 21:23:50 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2007-02-26 21:23:50 (GMT) |
commit | 0240b92a6c3a17fac38d93ee80fc8e8523388786 (patch) | |
tree | 8434f85d5b00ca30cc2fad24082ba454a43a4409 /Python/compile.c | |
parent | f74225d63b84a4d3b508fd5657cfe2596633876a (diff) | |
download | cpython-0240b92a6c3a17fac38d93ee80fc8e8523388786.zip cpython-0240b92a6c3a17fac38d93ee80fc8e8523388786.tar.gz cpython-0240b92a6c3a17fac38d93ee80fc8e8523388786.tar.bz2 |
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 ed0bdcf..7f0fc50 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)) |