Skip to content

Commit b533bad

Browse files
authored
Escape dictionary curly bracket before renderingin HTML (#42)
* Escape dictionary curly bracket before renderingin HTML * use mark_safe instead of format_html * add line * Use mark_safe one the html has been already escaped * no need to mark_safe a string * Add some basic tests for render_diff * add another case * add test docstring
1 parent fa1e2bb commit b533bad

2 files changed

Lines changed: 71 additions & 7 deletions

File tree

nautobot_ssot/templatetags/render_diff.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""Template tag for rendering a DiffSync diff dictionary in a more human-readable form."""
22

33
from django import template
4+
from django.utils.safestring import mark_safe
45
from django.utils.html import format_html
56

67

@@ -42,25 +43,24 @@ def render_diff_recursive(diff):
4243
child_class = "diff-unchanged"
4344
else:
4445
child_class = "diff-changed"
45-
child_result += f'<li class="{child_class}">{child}<ul>'
46+
child_result += format_html('<li class="{}">{}<ul>', child_class, child)
4647

4748
for attr, value in child_diffs.pop("+", {}).items():
48-
child_result += f'<li class="diff-added">{attr}: {value}</li>'
49+
child_result += format_html('<li class="diff-added">{}: {}</li>', attr, value)
4950

5051
for attr, value in child_diffs.pop("-", {}).items():
51-
child_result += f'<li class="diff-subtracted">{attr}: {value}</li>'
52+
child_result += format_html('<li class="diff-subtracted">{}: {}</li>', attr, value)
5253

5354
if child_diffs:
5455
child_result += render_diff_recursive(child_diffs)
5556

5657
child_result += "</ul></li>"
57-
result += f"<li>{record_type}<ul>{child_result}</ul></li>"
58+
result += format_html("<li>{}<ul>{}</ul></li>", record_type, mark_safe(child_result)) # nosec
5859
return result
5960

6061

6162
@register.simple_tag
6263
def render_diff(diff):
6364
"""Render a DiffSync diff dict to HTML."""
64-
result = f"<ul>{render_diff_recursive(diff)}</ul>"
65-
66-
return format_html(result)
65+
html_text = render_diff_recursive(diff)
66+
return format_html("<ul>{}</ul>", mark_safe(html_text)) # nosec
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
"""Test Render_diff templatetags."""
2+
import unittest
3+
from nautobot_ssot.templatetags.render_diff import render_diff
4+
5+
6+
test_params = [
7+
(
8+
{
9+
"region": {
10+
"Catalonia": {"+": {"parent_name": None}, "-": {"parent_name": "Europe"}},
11+
}
12+
},
13+
'<ul><li>region<ul><li class="diff-changed">Catalonia<ul><li class="diff-added">parent_name: None</li><li class="diff-subtracted">parent_name: Europe</li></ul></li></ul></li></ul>',
14+
),
15+
(
16+
{
17+
"region": {
18+
"Barcelona": {
19+
"+": {
20+
"cfs": {"asw_owner": ""},
21+
"slug": "barcelona",
22+
"description": "",
23+
"parent_name": "Catalonia",
24+
}
25+
},
26+
}
27+
},
28+
'<ul><li>region<ul><li class="diff-added">Barcelona<ul><li class="diff-added">cfs: {&#x27;asw_owner&#x27;: &#x27;&#x27;}</li><li class="diff-added">slug: barcelona</li><li class="diff-added">description: </li><li class="diff-added">parent_name: Catalonia</li></ul></li></ul></li></ul>',
29+
),
30+
(
31+
{
32+
"model_name": {
33+
"element": {
34+
"-": {
35+
"cfs": {"this is a XSS": "<script>alert(document.cookie)</script>"},
36+
}
37+
},
38+
}
39+
},
40+
'<ul><li>model_name<ul><li class="diff-subtracted">element<ul><li class="diff-subtracted">cfs: {&#x27;this is a XSS&#x27;: &#x27;&lt;script&gt;alert(document.cookie)&lt;/script&gt;&#x27;}</li></ul></li></ul></li></ul>',
41+
),
42+
(
43+
{
44+
"model_name": {
45+
"element": {
46+
"-": {
47+
"description": "<script>alert(document.cookie)</script>",
48+
}
49+
},
50+
}
51+
},
52+
'<ul><li>model_name<ul><li class="diff-subtracted">element<ul><li class="diff-subtracted">description: &lt;script&gt;alert(document.cookie)&lt;/script&gt;</li></ul></li></ul></li></ul>',
53+
),
54+
]
55+
56+
57+
class TestRenderDiff(unittest.TestCase):
58+
"""Tests for render_diff function."""
59+
60+
def test_render_diff_as_expected(self):
61+
"""Testing expected escaped and rendered HTML."""
62+
for input_dict, rendered_diff in test_params:
63+
with self.subTest():
64+
self.assertEqual(render_diff(input_dict), rendered_diff)

0 commit comments

Comments
 (0)