Mercurial > cpython-lru_cache-weakref
diff Python/compile.c @ 40943:c79e6234fb19
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.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Mon, 26 Feb 2007 21:23:50 +0000 |
| parents | 2ca14d6a369b |
| children | 30e5cb3a55ac |
line wrap: on
line diff
--- a/Python/compile.c Mon Feb 26 21:10:16 2007 +0000 +++ b/Python/compile.c Mon Feb 26 21:23:50 2007 +0000 @@ -836,6 +836,8 @@ 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 @@ else return -1; - case MAKE_CLOSURE: - return -oparg; case LOAD_CLOSURE: return 1; case LOAD_DEREF: @@ -1367,8 +1367,12 @@ 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 @@ } 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 @@ 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))
