Commit 7d9ac783 authored by Collin Winter's avatar Collin Winter

Patch #1642547: Fix an error/crash when encountering syntax errors in complex if statements.

Backported from r54404.
parent c1b4e8e6
...@@ -364,6 +364,56 @@ build. The number of blocks must be greater than CO_MAXBLOCKS. SF #1565514 ...@@ -364,6 +364,56 @@ build. The number of blocks must be greater than CO_MAXBLOCKS. SF #1565514
... ...
SystemError: too many statically nested blocks 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 import re
......
...@@ -12,6 +12,9 @@ What's New in Python 2.5.1c1? ...@@ -12,6 +12,9 @@ What's New in Python 2.5.1c1?
Core and builtins 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__()`` - Patch #1462488: Python no longer segfaults when ``object.__reduce_ex__()``
is called with an object that is faking its type. is called with an object that is faking its type.
......
...@@ -1033,6 +1033,7 @@ ast_for_listcomp(struct compiling *c, const node *n) ...@@ -1033,6 +1033,7 @@ ast_for_listcomp(struct compiling *c, const node *n)
if (NCH(ch) == 5) { if (NCH(ch) == 5) {
int j, n_ifs; int j, n_ifs;
asdl_seq *ifs; asdl_seq *ifs;
expr_ty list_for_expr;
ch = CHILD(ch, 4); ch = CHILD(ch, 4);
n_ifs = count_list_ifs(ch); n_ifs = count_list_ifs(ch);
...@@ -1047,8 +1048,12 @@ ast_for_listcomp(struct compiling *c, const node *n) ...@@ -1047,8 +1048,12 @@ ast_for_listcomp(struct compiling *c, const node *n)
REQ(ch, list_iter); REQ(ch, list_iter);
ch = CHILD(ch, 0); ch = CHILD(ch, 0);
REQ(ch, list_if); 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) if (NCH(ch) == 3)
ch = CHILD(ch, 2); ch = CHILD(ch, 2);
} }
...@@ -1992,7 +1997,8 @@ ast_for_expr_stmt(struct compiling *c, const node *n) ...@@ -1992,7 +1997,8 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
"assignment"); "assignment");
return NULL; return NULL;
} }
set_context(expr1, Store, ch); if (!set_context(expr1, Store, ch))
return NULL;
ch = CHILD(n, 2); ch = CHILD(n, 2);
if (TYPE(ch) == testlist) if (TYPE(ch) == testlist)
...@@ -2593,6 +2599,8 @@ ast_for_if_stmt(struct compiling *c, const node *n) ...@@ -2593,6 +2599,8 @@ ast_for_if_stmt(struct compiling *c, const node *n)
} }
else if (s[2] == 'i') { else if (s[2] == 'i') {
int i, n_elif, has_else = 0; int i, n_elif, has_else = 0;
expr_ty expression;
asdl_seq *suite_seq;
asdl_seq *orelse = NULL; asdl_seq *orelse = NULL;
n_elif = NCH(n) - 4; n_elif = NCH(n) - 4;
/* must reference the child n_elif+1 since 'else' token is third, /* 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) ...@@ -2605,8 +2613,7 @@ ast_for_if_stmt(struct compiling *c, const node *n)
n_elif /= 4; n_elif /= 4;
if (has_else) { if (has_else) {
expr_ty expression; asdl_seq *suite_seq2;
asdl_seq *seq1, *seq2;
orelse = asdl_seq_new(1, c->c_arena); orelse = asdl_seq_new(1, c->c_arena);
if (!orelse) if (!orelse)
...@@ -2614,14 +2621,14 @@ ast_for_if_stmt(struct compiling *c, const node *n) ...@@ -2614,14 +2621,14 @@ ast_for_if_stmt(struct compiling *c, const node *n)
expression = ast_for_expr(c, CHILD(n, NCH(n) - 6)); expression = ast_for_expr(c, CHILD(n, NCH(n) - 6));
if (!expression) if (!expression)
return NULL; return NULL;
seq1 = ast_for_suite(c, CHILD(n, NCH(n) - 4)); suite_seq = ast_for_suite(c, CHILD(n, NCH(n) - 4));
if (!seq1) if (!suite_seq)
return NULL; return NULL;
seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1)); suite_seq2 = ast_for_suite(c, CHILD(n, NCH(n) - 1));
if (!seq2) if (!suite_seq2)
return NULL; 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, LINENO(CHILD(n, NCH(n) - 6)), CHILD(n, NCH(n) - 6)->n_col_offset,
c->c_arena)); c->c_arena));
/* the just-created orelse handled the last elif */ /* the just-created orelse handled the last elif */
...@@ -2630,8 +2637,6 @@ ast_for_if_stmt(struct compiling *c, const node *n) ...@@ -2630,8 +2637,6 @@ ast_for_if_stmt(struct compiling *c, const node *n)
for (i = 0; i < n_elif; i++) { for (i = 0; i < n_elif; i++) {
int off = 5 + (n_elif - i - 1) * 4; 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); asdl_seq *newobj = asdl_seq_new(1, c->c_arena);
if (!newobj) if (!newobj)
return NULL; return NULL;
...@@ -2647,9 +2652,14 @@ ast_for_if_stmt(struct compiling *c, const node *n) ...@@ -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)); LINENO(CHILD(n, off)), CHILD(n, off)->n_col_offset, c->c_arena));
orelse = newobj; orelse = newobj;
} }
return If(ast_for_expr(c, CHILD(n, 1)), expression = ast_for_expr(c, CHILD(n, 1));
ast_for_suite(c, CHILD(n, 3)), if (!expression)
orelse, LINENO(n), n->n_col_offset, c->c_arena); 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, PyErr_Format(PyExc_SystemError,
...@@ -2889,6 +2899,8 @@ ast_for_with_stmt(struct compiling *c, const node *n) ...@@ -2889,6 +2899,8 @@ ast_for_with_stmt(struct compiling *c, const node *n)
assert(TYPE(n) == with_stmt); assert(TYPE(n) == with_stmt);
context_expr = ast_for_expr(c, CHILD(n, 1)); context_expr = ast_for_expr(c, CHILD(n, 1));
if (!context_expr)
return NULL;
if (TYPE(CHILD(n, 2)) == with_var) { if (TYPE(CHILD(n, 2)) == with_var) {
optional_vars = ast_for_with_var(c, CHILD(n, 2)); optional_vars = ast_for_with_var(c, CHILD(n, 2));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment