summaryrefslogtreecommitdiffstats
path: root/Python/compile.c
diff options
context:
space:
mode:
authorGuido van Rossum <guido@python.org>2007-02-26 21:23:50 (GMT)
committerGuido van Rossum <guido@python.org>2007-02-26 21:23:50 (GMT)
commit0240b92a6c3a17fac38d93ee80fc8e8523388786 (patch)
tree8434f85d5b00ca30cc2fad24082ba454a43a4409 /Python/compile.c
parentf74225d63b84a4d3b508fd5657cfe2596633876a (diff)
downloadcpython-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.c21
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))