| From ce67cd968bfc7c5d5df36e5990c3deed9b7368ef Mon Sep 17 00:00:00 2001 |
| From: Anil Altinay <aaltinay@google.com> |
| Date: Fri, 19 Jan 2024 22:51:36 +0000 |
| Subject: [PATCH] xmlattr filter disallows keys with spaces |
| |
| --- |
| src/jinja2/filters.py | 16 ++++++++++++++-- |
| tests/test_filters.py | 6 ++++++ |
| 2 files changed, 20 insertions(+), 2 deletions(-) |
| |
| diff --git a/src/jinja2/filters.py b/src/jinja2/filters.py |
| index 74b108d..056730c 100644 |
| --- a/src/jinja2/filters.py |
| +++ b/src/jinja2/filters.py |
| @@ -204,12 +204,13 @@ def do_lower(s): |
| """Convert a value to lowercase.""" |
| return soft_unicode(s).lower() |
| |
| +_space_re = re.compile(r"\s", flags=re.ASCII) |
| |
| @evalcontextfilter |
| def do_xmlattr(_eval_ctx, d, autospace=True): |
| """Create an SGML/XML attribute string based on the items in a dict. |
| - All values that are neither `none` nor `undefined` are automatically |
| - escaped: |
| + If any key contains a space, this fails with a ``ValueError``. Values that |
| + are neither ``none`` nor ``undefined`` are automatically escaped. |
| |
| .. sourcecode:: html+jinja |
| |
| @@ -234,6 +235,17 @@ def do_xmlattr(_eval_ctx, d, autospace=True): |
| for key, value in iteritems(d) |
| if value is not None and not isinstance(value, Undefined) |
| ) |
| + for key, value in d.items(): |
| + if value is None or isinstance(value, Undefined): |
| + continue |
| + |
| + if _space_re.search(key) is not None: |
| + raise ValueError(f"Spaces are not allowed in attributes: '{key}'") |
| + |
| + items.append(f'{escape(key)}="{escape(value)}"') |
| + |
| + rv = " ".join(items) |
| + |
| if autospace and rv: |
| rv = u" " + rv |
| if _eval_ctx.autoescape: |
| diff --git a/tests/test_filters.py b/tests/test_filters.py |
| index 388c346..52e333c 100644 |
| --- a/tests/test_filters.py |
| +++ b/tests/test_filters.py |
| @@ -158,6 +158,12 @@ class TestFilter(object): |
| tmpl = env.from_string("""{{ "%s|%s"|format("a", "b") }}""") |
| out = tmpl.render() |
| assert out == "a|b" |
| + |
| + def test_xmlattr_key_with_spaces(self, env): |
| + with pytest.raises(ValueError, match="Spaces are not allowed"): |
| + env.from_string( |
| + "{{ {'src=1 onerror=alert(1)': 'my_class'}|xmlattr }}" |
| + ).render() |
| |
| @staticmethod |
| def _test_indent_multiline_template(env, markup=False): |
| -- |
| 2.43.0.429.g432eaa2c6b-goog |
| |