Skip to content

Commit

Permalink
xmlattr filter disallows keys with spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
CalumHutton authored and davidism committed Jan 10, 2024
1 parent d84a174 commit 7dd3680
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
1 change: 1 addition & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Unreleased

- Fix compiler error when checking if required blocks in parent templates are
empty. :pr:`1858`
- ``xmlattr`` filter does not allow keys with spaces. GHSA-h5c8-rqwp-cp95


Version 3.1.2
Expand Down
28 changes: 21 additions & 7 deletions src/jinja2/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,13 +248,17 @@ def do_items(value: t.Union[t.Mapping[K, V], Undefined]) -> t.Iterator[t.Tuple[K
yield from value.items()


_space_re = re.compile(r"\s", flags=re.ASCII)


@pass_eval_context
def do_xmlattr(
eval_ctx: "EvalContext", d: t.Mapping[str, t.Any], autospace: bool = True
) -> str:
"""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
Expand All @@ -273,12 +277,22 @@ def do_xmlattr(
As you can see it automatically prepends a space in front of the item
if the filter returned something unless the second parameter is false.
.. versionchanged:: 3.1.3
Keys with spaces are not allowed.
"""
rv = " ".join(
f'{escape(key)}="{escape(value)}"'
for key, value in d.items()
if value is not None and not isinstance(value, Undefined)
)
items = []

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 = " " + rv
Expand Down
6 changes: 6 additions & 0 deletions tests/test_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -474,6 +474,12 @@ def test_xmlattr(self, env):
assert 'bar="23"' in out
assert 'blub:blub="<?>"' in out

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()

def test_sort1(self, env):
tmpl = env.from_string("{{ [2, 3, 1]|sort }}|{{ [2, 3, 1]|sort(true) }}")
assert tmpl.render() == "[1, 2, 3]|[3, 2, 1]"
Expand Down

0 comments on commit 7dd3680

Please # to comment.