Patch #1642547: Fix an error/crash when encountering syntax errors in complex if statements.
Will backport.
This commit is contained in:
parent
20f43d3018
commit
77c67bd585
|
@ -367,6 +367,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.6 alpha 1?
|
||||||
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.
|
||||||
|
|
||||||
|
|
40
Python/ast.c
40
Python/ast.c
|
@ -1032,6 +1032,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,7 +1048,11 @@ ast_for_listcomp(struct compiling *c, const node *n)
|
||||||
ch = CHILD(ch, 0);
|
ch = CHILD(ch, 0);
|
||||||
REQ(ch, list_if);
|
REQ(ch, list_if);
|
||||||
|
|
||||||
asdl_seq_SET(ifs, j, ast_for_expr(c, CHILD(ch, 1)));
|
list_for_expr = ast_for_expr(c, CHILD(ch, 1));
|
||||||
|
if (!list_for_expr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
asdl_seq_SET(ifs, j, list_for_expr);
|
||||||
if (NCH(ch) == 3)
|
if (NCH(ch) == 3)
|
||||||
ch = CHILD(ch, 2);
|
ch = CHILD(ch, 2);
|
||||||
}
|
}
|
||||||
|
@ -1991,7 +1996,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)
|
||||||
|
@ -2584,6 +2590,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,
|
||||||
|
@ -2596,8 +2604,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)
|
||||||
|
@ -2605,14 +2612,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 */
|
||||||
|
@ -2621,8 +2628,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;
|
||||||
|
@ -2638,9 +2643,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,
|
||||||
|
@ -2876,6 +2886,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));
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue