]> git.ipfire.org Git - thirdparty/jinja.git/commitdiff
fix f-string syntax error in code generation 1852/head
authorSigurd Spieckermann <sigurd.spieckermann@gmail.com>
Fri, 26 May 2023 12:32:36 +0000 (14:32 +0200)
committerDavid Lord <davidism@gmail.com>
Fri, 20 Dec 2024 02:08:42 +0000 (18:08 -0800)
CHANGES.rst
src/jinja2/compiler.py
tests/test_compile.py

index 0a569475733712d8e6b15f781c51972e43687d90..5d64b267cc50c599ed14c36499309cf647b004e9 100644 (file)
@@ -8,6 +8,9 @@ Unreleased
 -   The sandboxed environment handles indirect calls to ``str.format``, such as
     by passing a stored reference to a filter that calls its argument.
     :ghsa:`q2x7-8rv6-6q7h`
+-   Escape template name before formatting it into error messages, to avoid
+    issues with names that contain f-string syntax.
+    :issue:`1792`, :ghsa:`gmj6-6f8f-6699`
 -   Sandbox does not allow ``clear`` and ``pop`` on known mutable sequence
     types. :issue:`2032`
 -   Calling sync ``render`` for an async template uses ``asyncio.run``.
index 074e9b1871bb9584f7038ebb632ef16ef418322a..23295ec1fdb2902b749ed75ce12b014ad8a99a53 100644 (file)
@@ -1141,9 +1141,14 @@ class CodeGenerator(NodeVisitor):
             )
             self.writeline(f"if {frame.symbols.ref(alias)} is missing:")
             self.indent()
+            # The position will contain the template name, and will be formatted
+            # into a string that will be compiled into an f-string. Curly braces
+            # in the name must be replaced with escapes so that they will not be
+            # executed as part of the f-string.
+            position = self.position(node).replace("{", "{{").replace("}", "}}")
             message = (
                 "the template {included_template.__name__!r}"
-                f" (imported on {self.position(node)})"
+                f" (imported on {position})"
                 f" does not export the requested name {name!r}"
             )
             self.writeline(
index 42efa59c0f02e1268ea71b479883c085973dc113..e1a5391ea25d363d15e494570a1f0524aabec067 100644 (file)
@@ -1,6 +1,9 @@
 import os
 import re
 
+import pytest
+
+from jinja2 import UndefinedError
 from jinja2.environment import Environment
 from jinja2.loaders import DictLoader
 
@@ -87,3 +90,19 @@ def test_block_set_vars_unpacking_deterministic(tmp_path):
         content,
     )[:10]
     assert found == expect
+
+
+def test_undefined_import_curly_name():
+    env = Environment(
+        loader=DictLoader(
+            {
+                "{bad}": "{% from 'macro' import m %}{{ m() }}",
+                "macro": "",
+            }
+        )
+    )
+
+    # Must not raise `NameError: 'bad' is not defined`, as that would indicate
+    # that `{bad}` is being interpreted as an f-string. It must be escaped.
+    with pytest.raises(UndefinedError):
+        env.get_template("{bad}").render()