mirror of
https://github.com/django/django.git
synced 2025-12-23 09:19:27 +00:00
Fixed #36769 -- Avoided visiting deeply nested nodes in XML deserializer.
Only children at one level of depth need to be visited. Co-authored-by: Jacob Walls <jacobtylerwalls@gmail.com>
This commit is contained in:
parent
37eb890969
commit
dae08cf55b
3 changed files with 28 additions and 19 deletions
|
|
@ -416,27 +416,17 @@ class Deserializer(base.Deserializer):
|
|||
|
||||
|
||||
def getInnerText(node):
|
||||
"""Get all the inner text of a DOM node (recursively)."""
|
||||
inner_text_list = getInnerTextList(node)
|
||||
return "".join(inner_text_list)
|
||||
|
||||
|
||||
def getInnerTextList(node):
|
||||
"""Return a list of the inner texts of a DOM node (recursively)."""
|
||||
"""Get the inner text of a DOM node and any children one level deep."""
|
||||
# inspired by
|
||||
# https://mail.python.org/pipermail/xml-sig/2005-March/011022.html
|
||||
result = []
|
||||
for child in node.childNodes:
|
||||
if (
|
||||
child.nodeType == child.TEXT_NODE
|
||||
or child.nodeType == child.CDATA_SECTION_NODE
|
||||
):
|
||||
result.append(child.data)
|
||||
elif child.nodeType == child.ELEMENT_NODE:
|
||||
result.extend(getInnerTextList(child))
|
||||
else:
|
||||
pass
|
||||
return result
|
||||
return "".join(
|
||||
[
|
||||
element.data
|
||||
for child in node.childNodes
|
||||
for element in (child, *child.childNodes)
|
||||
if element.nodeType in (element.TEXT_NODE, element.CDATA_SECTION_NODE)
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
# Below code based on Christian Heimes' defusedxml
|
||||
|
|
|
|||
10
tests/fixtures/fixtures/invalid_deeply_nested_elements.xml
vendored
Normal file
10
tests/fixtures/fixtures/invalid_deeply_nested_elements.xml
vendored
Normal file
|
|
@ -0,0 +1,10 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<django-objects version="1.0">
|
||||
|
||||
<object pk="1" model="fixtures.person">
|
||||
<field type="CharField" name="name">
|
||||
<natural>Django <em>pony</em></natural>
|
||||
</field>
|
||||
</object>
|
||||
|
||||
</django-objects>
|
||||
9
tests/fixtures/tests.py
vendored
9
tests/fixtures/tests.py
vendored
|
|
@ -23,6 +23,7 @@ from .models import (
|
|||
CircularA,
|
||||
CircularB,
|
||||
NaturalKeyThing,
|
||||
Person,
|
||||
PrimaryKeyUUIDModel,
|
||||
ProxySpy,
|
||||
Spy,
|
||||
|
|
@ -520,6 +521,14 @@ class FixtureLoadingTests(DumpDataAssertMixin, TestCase):
|
|||
natural_foreign_keys=True,
|
||||
)
|
||||
|
||||
def test_deeply_nested_elements(self):
|
||||
"""Text inside deeply-nested tags is skipped."""
|
||||
management.call_command(
|
||||
"loaddata", "invalid_deeply_nested_elements.xml", verbosity=0
|
||||
)
|
||||
person = Person.objects.get(pk=1)
|
||||
self.assertEqual(person.name, "Django") # not "Django pony"
|
||||
|
||||
def test_dumpdata_with_excludes(self):
|
||||
# Load fixture1 which has a site, two articles, and a category
|
||||
Site.objects.all().delete()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue