From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Sat, 6 Jun 2020 17:04:47 +0000 (-0700) Subject: bpo-40870: Invalidate usage of some constants with ast.Name (GH-20649) X-Git-Tag: v3.8.4rc1~63 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=83a9ba442662c2a030b45955f3dd24ff4b24bb61;p=thirdparty%2FPython%2Fcpython.git bpo-40870: Invalidate usage of some constants with ast.Name (GH-20649) (cherry picked from commit 68874a8502da440a1dc4746cf73262648b870aee) Co-authored-by: Batuhan Taskaya --- diff --git a/Lib/test/test_ast.py b/Lib/test/test_ast.py index 869346664499..b921f4a5d682 100644 --- a/Lib/test/test_ast.py +++ b/Lib/test/test_ast.py @@ -635,6 +635,13 @@ class AST_Tests(unittest.TestCase): with self.assertRaises(SyntaxError): ast.parse('f"{x=}"', feature_version=(3, 7)) + def test_constant_as_name(self): + for constant in "True", "False", "None": + expr = ast.Expression(ast.Name(constant, ast.Load())) + ast.fix_missing_locations(expr) + with self.assertRaisesRegex(ValueError, f"Name node can't be used with '{constant}' constant"): + compile(expr, "", "eval") + class ASTHelpers_Test(unittest.TestCase): maxDiff = None diff --git a/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst new file mode 100644 index 000000000000..8e943a29f337 --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst @@ -0,0 +1,2 @@ +Raise :exc:`ValueError` when validating custom AST's where the constants +``True``, ``False`` and ``None`` are used within a :class:`ast.Name` node. diff --git a/Python/ast.c b/Python/ast.c index 594879bd0ef0..0a999fcca43a 100644 --- a/Python/ast.c +++ b/Python/ast.c @@ -21,6 +21,25 @@ static int validate_nonempty_seq(asdl_seq *, const char *, const char *); static int validate_stmt(stmt_ty); static int validate_expr(expr_ty, expr_context_ty); +static int +validate_name(PyObject *name) +{ + assert(PyUnicode_Check(name)); + static const char * const forbidden[] = { + "None", + "True", + "False", + NULL + }; + for (int i = 0; forbidden[i] != NULL; i++) { + if (_PyUnicode_EqualToASCIIString(name, forbidden[i])) { + PyErr_Format(PyExc_ValueError, "Name node can't be used with '%s' constant", forbidden[i]); + return 0; + } + } + return 1; +} + static int validate_comprehension(asdl_seq *gens) { @@ -199,6 +218,9 @@ validate_expr(expr_ty exp, expr_context_ty ctx) actual_ctx = exp->v.Starred.ctx; break; case Name_kind: + if (!validate_name(exp->v.Name.id)) { + return 0; + } actual_ctx = exp->v.Name.ctx; break; case List_kind: