]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
bpo-40870: Invalidate usage of some constants with ast.Name (GH-20649)
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Sat, 6 Jun 2020 17:04:47 +0000 (10:04 -0700)
committerGitHub <noreply@github.com>
Sat, 6 Jun 2020 17:04:47 +0000 (10:04 -0700)
(cherry picked from commit 68874a8502da440a1dc4746cf73262648b870aee)

Co-authored-by: Batuhan Taskaya <isidentical@gmail.com>
Lib/test/test_ast.py
Misc/NEWS.d/next/Core and Builtins/2020-06-05-12-48-28.bpo-40870.9cd2sk.rst [new file with mode: 0644]
Python/ast.c

index 869346664499c11288057f45814892ed8912a576..b921f4a5d6826905ab8dfcea0fc214cc39547a66 100644 (file)
@@ -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, "<test>", "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 (file)
index 0000000..8e943a2
--- /dev/null
@@ -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.
index 594879bd0ef0bd714a6148eba69879e6ae246780..0a999fcca43a8e2d1e730d4af44bec634992dc81 100644 (file)
@@ -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: