mirror of https://github.com/python/cpython
Merged revisions 84209, 84214 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/branches/py3k ........ r84209 | amaury.forgeotdarc | 2010-08-19 19:43:15 +0200 (jeu., 19 août 2010) | 5 lines Check the return values for all functions returning an ast node. Failure to do it may result in strange error messages or even crashes, in admittedly convoluted cases that are normally syntax errors, like: def f(*xx, __debug__): pass ........ r84214 | amaury.forgeotdarc | 2010-08-19 23:32:38 +0200 (jeu., 19 août 2010) | 3 lines Add tests for r84209 (crashes in the Ast builder) Also remove one tab, and move a check closer to the possible failure. ........
This commit is contained in:
parent
3478ac066b
commit
b1147f5d0a
|
@ -474,6 +474,12 @@ Traceback (most recent call last):
|
||||||
File "<doctest test.test_syntax[50]>", line 1
|
File "<doctest test.test_syntax[50]>", line 1
|
||||||
SyntaxError: can't assign to literal
|
SyntaxError: can't assign to literal
|
||||||
|
|
||||||
|
Corner-case that used to crash:
|
||||||
|
|
||||||
|
>>> def f(*xx, **__debug__): pass
|
||||||
|
Traceback (most recent call last):
|
||||||
|
SyntaxError: cannot assign to __debug__
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
40
Python/ast.c
40
Python/ast.c
|
@ -688,10 +688,10 @@ ast_for_arguments(struct compiling *c, const node *n)
|
||||||
}
|
}
|
||||||
args = (n_args ? asdl_seq_new(n_args, c->c_arena) : NULL);
|
args = (n_args ? asdl_seq_new(n_args, c->c_arena) : NULL);
|
||||||
if (!args && n_args)
|
if (!args && n_args)
|
||||||
return NULL; /* Don't need to goto error; no objects allocated */
|
return NULL;
|
||||||
defaults = (n_defaults ? asdl_seq_new(n_defaults, c->c_arena) : NULL);
|
defaults = (n_defaults ? asdl_seq_new(n_defaults, c->c_arena) : NULL);
|
||||||
if (!defaults && n_defaults)
|
if (!defaults && n_defaults)
|
||||||
return NULL; /* Don't need to goto error; no objects allocated */
|
return NULL;
|
||||||
|
|
||||||
/* fpdef: NAME | '(' fplist ')'
|
/* fpdef: NAME | '(' fplist ')'
|
||||||
fplist: fpdef (',' fpdef)* [',']
|
fplist: fpdef (',' fpdef)* [',']
|
||||||
|
@ -711,7 +711,7 @@ ast_for_arguments(struct compiling *c, const node *n)
|
||||||
if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) {
|
if (i + 1 < NCH(n) && TYPE(CHILD(n, i + 1)) == EQUAL) {
|
||||||
expr_ty expression = ast_for_expr(c, CHILD(n, i + 2));
|
expr_ty expression = ast_for_expr(c, CHILD(n, i + 2));
|
||||||
if (!expression)
|
if (!expression)
|
||||||
goto error;
|
return NULL;
|
||||||
assert(defaults != NULL);
|
assert(defaults != NULL);
|
||||||
asdl_seq_SET(defaults, j++, expression);
|
asdl_seq_SET(defaults, j++, expression);
|
||||||
i += 2;
|
i += 2;
|
||||||
|
@ -722,11 +722,11 @@ ast_for_arguments(struct compiling *c, const node *n)
|
||||||
def f((x, (y))): pass will just incur the tuple unpacking warning. */
|
def f((x, (y))): pass will just incur the tuple unpacking warning. */
|
||||||
if (parenthesized && !complex_args) {
|
if (parenthesized && !complex_args) {
|
||||||
ast_error(n, "parenthesized arg with default");
|
ast_error(n, "parenthesized arg with default");
|
||||||
goto error;
|
return NULL;
|
||||||
}
|
}
|
||||||
ast_error(n,
|
ast_error(n,
|
||||||
"non-default argument follows default argument");
|
"non-default argument follows default argument");
|
||||||
goto error;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (NCH(ch) == 3) {
|
if (NCH(ch) == 3) {
|
||||||
ch = CHILD(ch, 1);
|
ch = CHILD(ch, 1);
|
||||||
|
@ -735,11 +735,11 @@ ast_for_arguments(struct compiling *c, const node *n)
|
||||||
/* We have complex arguments, setup for unpacking. */
|
/* We have complex arguments, setup for unpacking. */
|
||||||
if (Py_Py3kWarningFlag && !ast_warn(c, ch,
|
if (Py_Py3kWarningFlag && !ast_warn(c, ch,
|
||||||
"tuple parameter unpacking has been removed in 3.x"))
|
"tuple parameter unpacking has been removed in 3.x"))
|
||||||
goto error;
|
return NULL;
|
||||||
complex_args = 1;
|
complex_args = 1;
|
||||||
asdl_seq_SET(args, k++, compiler_complex_args(c, ch));
|
asdl_seq_SET(args, k++, compiler_complex_args(c, ch));
|
||||||
if (!asdl_seq_GET(args, k-1))
|
if (!asdl_seq_GET(args, k-1))
|
||||||
goto error;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
/* def foo((x)): setup for checking NAME below. */
|
/* def foo((x)): setup for checking NAME below. */
|
||||||
/* Loop because there can be many parens and tuple
|
/* Loop because there can be many parens and tuple
|
||||||
|
@ -754,14 +754,14 @@ ast_for_arguments(struct compiling *c, const node *n)
|
||||||
PyObject *id;
|
PyObject *id;
|
||||||
expr_ty name;
|
expr_ty name;
|
||||||
if (!forbidden_check(c, n, STR(CHILD(ch, 0))))
|
if (!forbidden_check(c, n, STR(CHILD(ch, 0))))
|
||||||
goto error;
|
return NULL;
|
||||||
id = NEW_IDENTIFIER(CHILD(ch, 0));
|
id = NEW_IDENTIFIER(CHILD(ch, 0));
|
||||||
if (!id)
|
if (!id)
|
||||||
goto error;
|
return NULL;
|
||||||
name = Name(id, Param, LINENO(ch), ch->n_col_offset,
|
name = Name(id, Param, LINENO(ch), ch->n_col_offset,
|
||||||
c->c_arena);
|
c->c_arena);
|
||||||
if (!name)
|
if (!name)
|
||||||
goto error;
|
return NULL;
|
||||||
asdl_seq_SET(args, k++, name);
|
asdl_seq_SET(args, k++, name);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -769,40 +769,35 @@ ast_for_arguments(struct compiling *c, const node *n)
|
||||||
if (parenthesized && Py_Py3kWarningFlag &&
|
if (parenthesized && Py_Py3kWarningFlag &&
|
||||||
!ast_warn(c, ch, "parenthesized argument names "
|
!ast_warn(c, ch, "parenthesized argument names "
|
||||||
"are invalid in 3.x"))
|
"are invalid in 3.x"))
|
||||||
goto error;
|
return NULL;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case STAR:
|
case STAR:
|
||||||
if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
|
if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
|
||||||
goto error;
|
return NULL;
|
||||||
vararg = NEW_IDENTIFIER(CHILD(n, i+1));
|
vararg = NEW_IDENTIFIER(CHILD(n, i+1));
|
||||||
if (!vararg)
|
if (!vararg)
|
||||||
goto error;
|
return NULL;
|
||||||
i += 3;
|
i += 3;
|
||||||
break;
|
break;
|
||||||
case DOUBLESTAR:
|
case DOUBLESTAR:
|
||||||
if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
|
if (!forbidden_check(c, CHILD(n, i+1), STR(CHILD(n, i+1))))
|
||||||
goto error;
|
return NULL;
|
||||||
kwarg = NEW_IDENTIFIER(CHILD(n, i+1));
|
kwarg = NEW_IDENTIFIER(CHILD(n, i+1));
|
||||||
if (!kwarg)
|
if (!kwarg)
|
||||||
goto error;
|
return NULL;
|
||||||
i += 3;
|
i += 3;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
PyErr_Format(PyExc_SystemError,
|
PyErr_Format(PyExc_SystemError,
|
||||||
"unexpected node in varargslist: %d @ %d",
|
"unexpected node in varargslist: %d @ %d",
|
||||||
TYPE(ch), i);
|
TYPE(ch), i);
|
||||||
goto error;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return arguments(args, vararg, kwarg, defaults, c->c_arena);
|
return arguments(args, vararg, kwarg, defaults, c->c_arena);
|
||||||
|
|
||||||
error:
|
|
||||||
Py_XDECREF(vararg);
|
|
||||||
Py_XDECREF(kwarg);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static expr_ty
|
static expr_ty
|
||||||
|
@ -2247,11 +2242,10 @@ ast_for_expr_stmt(struct compiling *c, const node *n)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
e = ast_for_testlist(c, ch);
|
e = ast_for_testlist(c, ch);
|
||||||
|
|
||||||
/* set context to assign */
|
|
||||||
if (!e)
|
if (!e)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
/* set context to assign */
|
||||||
if (!set_context(c, e, Store, CHILD(n, i)))
|
if (!set_context(c, e, Store, CHILD(n, i)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue