summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhaileyajohnson <haj022@ucsd.edu>2025-06-16 14:22:34 -0700
committerSarah Boyce <42296566+sarahboyce@users.noreply.github.com>2025-06-18 14:04:39 +0200
commit22506b2c162b34c4c45f748cf11ede75824a40cd (patch)
tree48649b38164cf002291db5b881038ea78e6943bd
parentdb4d65f8be1627223707185edac7181584425149 (diff)
Fixed #36465, Refs #35816 -- Disallowed '+' and '-' characters in template variable names.
Regression in 5183f7c287a9a5d61ca1103b55166cda52d9c647. Thank you to Jon Banafato and Baptiste Mispelon for the report.
-rw-r--r--django/template/base.py7
-rw-r--r--tests/template_tests/test_base.py5
-rw-r--r--tests/template_tests/test_parser.py28
3 files changed, 34 insertions, 6 deletions
diff --git a/django/template/base.py b/django/template/base.py
index 140f713add..121a47d638 100644
--- a/django/template/base.py
+++ b/django/template/base.py
@@ -852,6 +852,13 @@ class Variable:
"Variables and attributes may "
"not begin with underscores: '%s'" % var
)
+ # Disallow characters that are allowed in numbers but not in a
+ # variable name.
+ for c in ["+", "-"]:
+ if c in var:
+ raise TemplateSyntaxError(
+ "Invalid character ('%s') in variable name: '%s'" % (c, var)
+ )
self.lookups = tuple(var.split(VARIABLE_ATTRIBUTE_SEPARATOR))
def resolve(self, context):
diff --git a/tests/template_tests/test_base.py b/tests/template_tests/test_base.py
index 6457d4d4e6..33a200c362 100644
--- a/tests/template_tests/test_base.py
+++ b/tests/template_tests/test_base.py
@@ -78,9 +78,6 @@ class VariableTests(SimpleTestCase):
def test_nonliterals(self):
"""Variable names that aren't resolved as literals."""
- var_names = []
- for var in ("inf", "infinity", "iNFiniTy", "nan"):
- var_names.extend((var, "-" + var, "+" + var))
- for var in var_names:
+ for var in ["inf", "infinity", "iNFiniTy", "nan"]:
with self.subTest(var=var):
self.assertIsNone(Variable(var).literal)
diff --git a/tests/template_tests/test_parser.py b/tests/template_tests/test_parser.py
index c54f481f36..317fb88238 100644
--- a/tests/template_tests/test_parser.py
+++ b/tests/template_tests/test_parser.py
@@ -126,6 +126,16 @@ class ParserTests(SimpleTestCase):
):
Variable({})
+ # Variables should raise when invalid characters in name.
+ for c in ["+", "-"]:
+ with self.subTest(invalid_character=c):
+ variable_name = f"variable{c}name"
+ with self.assertRaisesMessage(
+ TemplateSyntaxError,
+ f"Invalid character ('{c}') in variable name: '{variable_name}'",
+ ):
+ Variable(variable_name)
+
def test_filter_args_count(self):
parser = Parser("")
register = Library()
@@ -174,6 +184,7 @@ class ParserTests(SimpleTestCase):
def test_filter_numeric_argument_parsing(self):
p = Parser("", builtins=[filter_library])
+ # Values that resolve to a numeric literal.
cases = {
"5": 5,
"-5": -5,
@@ -193,6 +204,7 @@ class ParserTests(SimpleTestCase):
FilterExpression(f"0|default:{num}", p).resolve({}), expected
)
+ # Values that are interpreted as names of variables that do not exist.
invalid_numbers = [
"abc123",
"123abc",
@@ -205,8 +217,6 @@ class ParserTests(SimpleTestCase):
"1e2.0",
"1e2a",
"1e2e3",
- "1e-",
- "1e-a",
]
for num in invalid_numbers:
@@ -216,3 +226,17 @@ class ParserTests(SimpleTestCase):
)
with self.assertRaises(VariableDoesNotExist):
FilterExpression(f"0|default:{num}", p).resolve({})
+
+ # Values that are interpreted as an invalid variable name.
+ invalid_numbers_and_var_names = [
+ "1e-",
+ "1e-a",
+ "1+1",
+ "1-1",
+ ]
+ for num in invalid_numbers_and_var_names:
+ with self.subTest(num=num):
+ with self.assertRaises(TemplateSyntaxError):
+ FilterExpression(num, p).resolve({})
+ with self.assertRaises(TemplateSyntaxError):
+ FilterExpression(f"0|default:{num}", p).resolve({})