diff --git a/tests/data/html/xss.html b/tests/data/html/xss.html
new file mode 100644
index 0000000..fbf12ab
--- /dev/null
+++ b/tests/data/html/xss.html
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/tests/data/json/embed-no_caption.json b/tests/data/json/embed-no_caption.json
index 00becda..4dbe785 100644
--- a/tests/data/json/embed-no_caption.json
+++ b/tests/data/json/embed-no_caption.json
@@ -16,5 +16,5 @@
"html": ""
}
}
- ]
+ ]
}
diff --git a/tests/data/json/featuredimage.json b/tests/data/json/featuredimage.json
index 8efedd5..578e899 100644
--- a/tests/data/json/featuredimage.json
+++ b/tests/data/json/featuredimage.json
@@ -4,10 +4,13 @@
{
"type": "featuredimage",
"attrs": {
- "src": { "image": "https://placekitten.com/200/301", "fallback": "https://placekitten.com/198/654" },
+ "src": {
+ "image": "https://placekitten.com/200/301",
+ "fallback": "https://placekitten.com/198/654"
+ },
"alt": "Brown Kitten Image",
"caption": "Cute Kitty"
}
}
- ]
+ ]
}
diff --git a/tests/data/json/xss.json b/tests/data/json/xss.json
new file mode 100644
index 0000000..0f24695
--- /dev/null
+++ b/tests/data/json/xss.json
@@ -0,0 +1,40 @@
+{
+ "type": "doc",
+ "attrs": {
+ "data": {
+ "foo": "bar",
+ ">": "\">"
+ }
+ },
+ "content": [
+ {
+ "type": "featuredimage",
+ "attrs": {
+ "src": {
+ "image": "\">",
+ "fallback": "\">"
+ },
+ "alt": "\">",
+ "caption": ""
+ }
+ },
+ {
+ "type": "paragraph",
+ "content": [
+ {
+ "type": "text",
+ "marks": [
+ {
+ "type": "link",
+ "attrs": {
+ "\" onmouseover=\"alert('pwned!')\"=\"": "\" onmouseover=\"alert('pwned!')\"=\"",
+ "foo": "bar"
+ }
+ }
+ ],
+ "text": ""
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/test_transform.py b/tests/test_transform.py
index 75c3822..be02a58 100644
--- a/tests/test_transform.py
+++ b/tests/test_transform.py
@@ -43,6 +43,7 @@
"document-sketch",
"camel-case",
"data_attributes",
+ "xss",
)
diff --git a/tiptapy/__init__.py b/tiptapy/__init__.py
index c51f76b..c3face7 100644
--- a/tiptapy/__init__.py
+++ b/tiptapy/__init__.py
@@ -50,7 +50,8 @@ def escape_values_recursive(node):
skip_key = "html"
if isinstance(node, dict):
- for k, v in node.items():
+ items = list(node.items())
+ for k, v in items:
esc_k = escape(k)
if k != esc_k:
del node[k]