]> granicus.if.org Git - python/commitdiff
Patch #1642547: Fix an error/crash when encountering syntax errors in complex if...
authorCollin Winter <collinw@gmail.com>
Fri, 16 Mar 2007 04:12:48 +0000 (04:12 +0000)
committerCollin Winter <collinw@gmail.com>
Fri, 16 Mar 2007 04:12:48 +0000 (04:12 +0000)
Backported from r54404.

Lib/test/test_syntax.py
Misc/NEWS
Python/ast.c

index 40991492a4391f6f3514a5793ae0aa6e380c4d5f..ef8e9a24c64612eb6cd2a02342c53613d3e52c95 100644 (file)
@@ -364,6 +364,56 @@ build.  The number of blocks must be greater than CO_MAXBLOCKS.  SF #1565514
      ...
    SystemError: too many statically nested blocks
 
+This tests assignment-context; there was a bug in Python 2.5 where compiling
+a complex 'if' (one with 'elif') would fail to notice an invalid suite,
+leading to spurious errors.
+
+   >>> if 1:
+   ...   x() = 1
+   ... elif 1:
+   ...   pass
+   Traceback (most recent call last):
+     ... 
+   SyntaxError: can't assign to function call (<doctest test.test_syntax[44]>, line 2)
+
+   >>> if 1:
+   ...   pass
+   ... elif 1:
+   ...   x() = 1
+   Traceback (most recent call last):
+     ... 
+   SyntaxError: can't assign to function call (<doctest test.test_syntax[45]>, line 4)
+
+   >>> if 1:
+   ...   x() = 1
+   ... elif 1:
+   ...   pass
+   ... else:
+   ...   pass
+   Traceback (most recent call last):
+     ... 
+   SyntaxError: can't assign to function call (<doctest test.test_syntax[46]>, line 2)
+
+   >>> if 1:
+   ...   pass
+   ... elif 1:
+   ...   x() = 1
+   ... else:
+   ...   pass
+   Traceback (most recent call last):
+     ... 
+   SyntaxError: can't assign to function call (<doctest test.test_syntax[47]>, line 4)
+
+   >>> if 1:
+   ...   pass
+   ... elif 1:
+   ...   pass
+   ... else:
+   ...   x() = 1
+   Traceback (most recent call last):
+     ... 
+   SyntaxError: can't assign to function call (<doctest test.test_syntax[48]>, line 6)
+
 """
 
 import re
index 287bac43dfa56539187a4a9067f3e37ec837f407..791fa83384ab14476664f7a44178c7a2d84c968c 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 2.5.1c1?
 Core and builtins
 -----------------
 
+- Patch #1642547: Fix an error/crash when encountering syntax errors in
+  complex if statements.
+
 - Patch #1462488: Python no longer segfaults when ``object.__reduce_ex__()``
   is called with an object that is faking its type.
 
index 6551063a7b8734fbf3f22e9645f251c85d4b388d..67f45ed0680ab7840897ef4908c16aa04acf69e7 100644 (file)
@@ -1033,6 +1033,7 @@ ast_for_listcomp(struct compiling *c, const node *n)
        if (NCH(ch) == 5) {
            int j, n_ifs;
            asdl_seq *ifs;
+           expr_ty list_for_expr;
 
            ch = CHILD(ch, 4);
            n_ifs = count_list_ifs(ch);
@@ -1047,8 +1048,12 @@ ast_for_listcomp(struct compiling *c, const node *n)
             REQ(ch, list_iter);
                    ch = CHILD(ch, 0);
                    REQ(ch, list_if);
+            
+                   list_for_expr = ast_for_expr(c, CHILD(ch, 1));
+                   if (!list_for_expr)
+                       return NULL;
 
-               asdl_seq_SET(ifs, j, ast_for_expr(c, CHILD(ch, 1)));
+               asdl_seq_SET(ifs, j, list_for_expr);
                if (NCH(ch) == 3)
                    ch = CHILD(ch, 2);
                }
@@ -1992,7 +1997,8 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
                           "assignment");
                 return NULL;
         }
-       set_context(expr1, Store, ch);
+       if (!set_context(expr1, Store, ch))
+               return NULL;
 
        ch = CHILD(n, 2);
        if (TYPE(ch) == testlist)
@@ -2593,6 +2599,8 @@ ast_for_if_stmt(struct compiling *c, const node *n)
     }
     else if (s[2] == 'i') {
        int i, n_elif, has_else = 0;
+       expr_ty expression;
+       asdl_seq *suite_seq;
        asdl_seq *orelse = NULL;
        n_elif = NCH(n) - 4;
         /* must reference the child n_elif+1 since 'else' token is third,
@@ -2605,8 +2613,7 @@ ast_for_if_stmt(struct compiling *c, const node *n)
        n_elif /= 4;
 
        if (has_else) {
-            expr_ty expression;
-            asdl_seq *seq1, *seq2;
+            asdl_seq *suite_seq2;
 
            orelse = asdl_seq_new(1, c->c_arena);
            if (!orelse)
@@ -2614,14 +2621,14 @@ ast_for_if_stmt(struct compiling *c, const node *n)
             expression = ast_for_expr(c, CHILD(n, NCH(n) - 6));
             if (!expression)
                 return NULL;
-            seq1 = ast_for_suite(c, CHILD(n, NCH(n) - 4));
-            if (!seq1)
+            suite_seq = ast_for_suite(c, CHILD(n, NCH(n) - 4));
+            if (!suite_seq)
                 return NULL;
-            seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
-            if (!seq2)
+            suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
+            if (!suite_seq2)
                 return NULL;
 
-           asdl_seq_SET(orelse, 0, If(expression, seq1, seq2, 
+           asdl_seq_SET(orelse, 0, If(expression, suite_seq, suite_seq2, 
                                       LINENO(CHILD(n, NCH(n) - 6)), CHILD(n, NCH(n) - 6)->n_col_offset,
                                        c->c_arena));
            /* the just-created orelse handled the last elif */
@@ -2630,8 +2637,6 @@ ast_for_if_stmt(struct compiling *c, const node *n)
 
        for (i = 0; i < n_elif; i++) {
            int off = 5 + (n_elif - i - 1) * 4;
-            expr_ty expression;
-            asdl_seq *suite_seq;
            asdl_seq *newobj = asdl_seq_new(1, c->c_arena);
            if (!newobj)
                return NULL;
@@ -2647,9 +2652,14 @@ ast_for_if_stmt(struct compiling *c, const node *n)
                            LINENO(CHILD(n, off)), CHILD(n, off)->n_col_offset, c->c_arena));
            orelse = newobj;
        }
-       return If(ast_for_expr(c, CHILD(n, 1)),
-                 ast_for_suite(c, CHILD(n, 3)),
-                 orelse, LINENO(n), n->n_col_offset, c->c_arena);
+       expression = ast_for_expr(c, CHILD(n, 1));
+       if (!expression)
+               return NULL;
+       suite_seq = ast_for_suite(c, CHILD(n, 3));
+       if (!suite_seq)
+               return NULL;
+       return If(expression, suite_seq, orelse,
+                         LINENO(n), n->n_col_offset, c->c_arena);
     }
 
     PyErr_Format(PyExc_SystemError,
@@ -2889,6 +2899,8 @@ ast_for_with_stmt(struct compiling *c, const node *n)
 
     assert(TYPE(n) == with_stmt);
     context_expr = ast_for_expr(c, CHILD(n, 1));
+    if (!context_expr)
+        return NULL;
     if (TYPE(CHILD(n, 2)) == with_var) {
         optional_vars = ast_for_with_var(c, CHILD(n, 2));