mirror of https://github.com/python/cpython
GH-105588: Add missing error checks to some obj2ast_* converters (GH-105589)
This commit is contained in:
parent
3af2dc7588
commit
a4056c8f9c
|
@ -3,6 +3,7 @@ import builtins
|
||||||
import dis
|
import dis
|
||||||
import enum
|
import enum
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import textwrap
|
import textwrap
|
||||||
import types
|
import types
|
||||||
|
@ -1110,6 +1111,32 @@ class AST_Tests(unittest.TestCase):
|
||||||
msg="source code string cannot contain null bytes"):
|
msg="source code string cannot contain null bytes"):
|
||||||
ast.parse("a\0b")
|
ast.parse("a\0b")
|
||||||
|
|
||||||
|
def assert_none_check(self, node: type[ast.AST], attr: str, source: str) -> None:
|
||||||
|
with self.subTest(f"{node.__name__}.{attr}"):
|
||||||
|
tree = ast.parse(source)
|
||||||
|
found = 0
|
||||||
|
for child in ast.walk(tree):
|
||||||
|
if isinstance(child, node):
|
||||||
|
setattr(child, attr, None)
|
||||||
|
found += 1
|
||||||
|
self.assertEqual(found, 1)
|
||||||
|
e = re.escape(f"field '{attr}' is required for {node.__name__}")
|
||||||
|
with self.assertRaisesRegex(ValueError, f"^{e}$"):
|
||||||
|
compile(tree, "<test>", "exec")
|
||||||
|
|
||||||
|
def test_none_checks(self) -> None:
|
||||||
|
tests = [
|
||||||
|
(ast.alias, "name", "import spam as SPAM"),
|
||||||
|
(ast.arg, "arg", "def spam(SPAM): spam"),
|
||||||
|
(ast.comprehension, "target", "[spam for SPAM in spam]"),
|
||||||
|
(ast.comprehension, "iter", "[spam for spam in SPAM]"),
|
||||||
|
(ast.keyword, "value", "spam(**SPAM)"),
|
||||||
|
(ast.match_case, "pattern", "match spam:\n case SPAM: spam"),
|
||||||
|
(ast.withitem, "context_expr", "with SPAM: spam"),
|
||||||
|
]
|
||||||
|
for node, attr, source in tests:
|
||||||
|
self.assert_none_check(node, attr, source)
|
||||||
|
|
||||||
class ASTHelpers_Test(unittest.TestCase):
|
class ASTHelpers_Test(unittest.TestCase):
|
||||||
maxDiff = None
|
maxDiff = None
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
Fix an issue that could result in crashes when compiling malformed
|
||||||
|
:mod:`ast` nodes.
|
|
@ -601,6 +601,7 @@ class Obj2ModVisitor(PickleVisitor):
|
||||||
args = [f.name for f in prod.fields]
|
args = [f.name for f in prod.fields]
|
||||||
args.extend([a.name for a in prod.attributes])
|
args.extend([a.name for a in prod.attributes])
|
||||||
self.emit("*out = %s(%s);" % (ast_func_name(name), self.buildArgs(args)), 1)
|
self.emit("*out = %s(%s);" % (ast_func_name(name), self.buildArgs(args)), 1)
|
||||||
|
self.emit("if (*out == NULL) goto failed;", 1)
|
||||||
self.emit("return 0;", 1)
|
self.emit("return 0;", 1)
|
||||||
self.emit("failed:", 0)
|
self.emit("failed:", 0)
|
||||||
self.emit("Py_XDECREF(tmp);", 1)
|
self.emit("Py_XDECREF(tmp);", 1)
|
||||||
|
|
|
@ -10834,6 +10834,7 @@ obj2ast_comprehension(struct ast_state *state, PyObject* obj, comprehension_ty*
|
||||||
Py_CLEAR(tmp);
|
Py_CLEAR(tmp);
|
||||||
}
|
}
|
||||||
*out = _PyAST_comprehension(target, iter, ifs, is_async, arena);
|
*out = _PyAST_comprehension(target, iter, ifs, is_async, arena);
|
||||||
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
failed:
|
failed:
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
|
@ -11258,6 +11259,7 @@ obj2ast_arguments(struct ast_state *state, PyObject* obj, arguments_ty* out,
|
||||||
}
|
}
|
||||||
*out = _PyAST_arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults,
|
*out = _PyAST_arguments(posonlyargs, args, vararg, kwonlyargs, kw_defaults,
|
||||||
kwarg, defaults, arena);
|
kwarg, defaults, arena);
|
||||||
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
failed:
|
failed:
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
|
@ -11397,6 +11399,7 @@ obj2ast_arg(struct ast_state *state, PyObject* obj, arg_ty* out, PyArena* arena)
|
||||||
}
|
}
|
||||||
*out = _PyAST_arg(arg, annotation, type_comment, lineno, col_offset,
|
*out = _PyAST_arg(arg, annotation, type_comment, lineno, col_offset,
|
||||||
end_lineno, end_col_offset, arena);
|
end_lineno, end_col_offset, arena);
|
||||||
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
failed:
|
failed:
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
|
@ -11519,6 +11522,7 @@ obj2ast_keyword(struct ast_state *state, PyObject* obj, keyword_ty* out,
|
||||||
}
|
}
|
||||||
*out = _PyAST_keyword(arg, value, lineno, col_offset, end_lineno,
|
*out = _PyAST_keyword(arg, value, lineno, col_offset, end_lineno,
|
||||||
end_col_offset, arena);
|
end_col_offset, arena);
|
||||||
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
failed:
|
failed:
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
|
@ -11641,6 +11645,7 @@ obj2ast_alias(struct ast_state *state, PyObject* obj, alias_ty* out, PyArena*
|
||||||
}
|
}
|
||||||
*out = _PyAST_alias(name, asname, lineno, col_offset, end_lineno,
|
*out = _PyAST_alias(name, asname, lineno, col_offset, end_lineno,
|
||||||
end_col_offset, arena);
|
end_col_offset, arena);
|
||||||
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
failed:
|
failed:
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
|
@ -11690,6 +11695,7 @@ obj2ast_withitem(struct ast_state *state, PyObject* obj, withitem_ty* out,
|
||||||
Py_CLEAR(tmp);
|
Py_CLEAR(tmp);
|
||||||
}
|
}
|
||||||
*out = _PyAST_withitem(context_expr, optional_vars, arena);
|
*out = _PyAST_withitem(context_expr, optional_vars, arena);
|
||||||
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
failed:
|
failed:
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
|
@ -11778,6 +11784,7 @@ obj2ast_match_case(struct ast_state *state, PyObject* obj, match_case_ty* out,
|
||||||
Py_CLEAR(tmp);
|
Py_CLEAR(tmp);
|
||||||
}
|
}
|
||||||
*out = _PyAST_match_case(pattern, guard, body, arena);
|
*out = _PyAST_match_case(pattern, guard, body, arena);
|
||||||
|
if (*out == NULL) goto failed;
|
||||||
return 0;
|
return 0;
|
||||||
failed:
|
failed:
|
||||||
Py_XDECREF(tmp);
|
Py_XDECREF(tmp);
|
||||||
|
|
Loading…
Reference in New Issue