Skip to content

Commit c3cc751

Browse files
vstinnerstratakisencukou
authored
bpo-35052: Fix handler on xml.dom.minidom.cloneNode() (GH-11061) (GH-11066)
Fix xml.dom.minidom cloneNode() on a document with an entity: pass the correct arguments to the user data handler of an entity (fix an old copy/paste mistake). Bug spotted and fix proposed by Charalampos Stratakis, initial reproducer written by Petr Viktorin. Co-Authored-By: Charalampos Stratakis <cstratak@redhat.com> Co-Authored-By: Petr Viktorin <encukou@gmail.com> (cherry picked from commit 8e04186)
1 parent fc79175 commit c3cc751

3 files changed

Lines changed: 57 additions & 4 deletions

File tree

Lib/test/test_minidom.py

Lines changed: 53 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import copy
44
import pickle
5-
from test.support import findfile
5+
from test import support
66
import unittest
77

88
import xml.dom.minidom
@@ -11,7 +11,7 @@
1111
from xml.dom.minidom import getDOMImplementation
1212

1313

14-
tstfile = findfile("test.xml", subdir="xmltestdata")
14+
tstfile = support.findfile("test.xml", subdir="xmltestdata")
1515
sample = ("<?xml version='1.0' encoding='us-ascii'?>\n"
1616
"<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
1717
" 'http://xml.python.org/system' [\n"
@@ -836,6 +836,57 @@ def testClonePIShallow(self):
836836
def testClonePIDeep(self):
837837
self.check_clone_pi(1, "testClonePIDeep")
838838

839+
def check_clone_node_entity(self, clone_document):
840+
# bpo-35052: Test user data handler in cloneNode() on a document with
841+
# an entity
842+
document = xml.dom.minidom.parseString("""
843+
<?xml version="1.0" ?>
844+
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
845+
"http://www.w3.org/TR/html4/strict.dtd"
846+
[ <!ENTITY smile "☺"> ]
847+
>
848+
<doc>Don't let entities make you frown &smile;</doc>
849+
""".strip())
850+
851+
class Handler:
852+
def handle(self, operation, key, data, src, dst):
853+
self.operation = operation
854+
self.key = key
855+
self.data = data
856+
self.src = src
857+
self.dst = dst
858+
859+
handler = Handler()
860+
doctype = document.doctype
861+
entity = doctype.entities['smile']
862+
entity.setUserData("key", "data", handler)
863+
864+
if clone_document:
865+
# clone Document
866+
clone = document.cloneNode(deep=True)
867+
868+
self.assertEqual(clone.documentElement.firstChild.wholeText,
869+
"Don't let entities make you frown ☺")
870+
operation = xml.dom.UserDataHandler.NODE_IMPORTED
871+
dst = clone.doctype.entities['smile']
872+
else:
873+
# clone DocumentType
874+
with support.swap_attr(doctype, 'ownerDocument', None):
875+
clone = doctype.cloneNode(deep=True)
876+
877+
operation = xml.dom.UserDataHandler.NODE_CLONED
878+
dst = clone.entities['smile']
879+
880+
self.assertEqual(handler.operation, operation)
881+
self.assertEqual(handler.key, "key")
882+
self.assertEqual(handler.data, "data")
883+
self.assertIs(handler.src, entity)
884+
self.assertIs(handler.dst, dst)
885+
886+
def testCloneNodeEntity(self):
887+
self.check_clone_node_entity(False)
888+
self.check_clone_node_entity(True)
889+
839890
def testNormalize(self):
840891
doc = parseString("<doc/>")
841892
root = doc.documentElement

Lib/xml/dom/minidom.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1318,7 +1318,7 @@ def cloneNode(self, deep):
13181318
entity.encoding = e.encoding
13191319
entity.version = e.version
13201320
clone.entities._seq.append(entity)
1321-
e._call_user_data_handler(operation, n, entity)
1321+
e._call_user_data_handler(operation, e, entity)
13221322
self._call_user_data_handler(operation, self, clone)
13231323
return clone
13241324
else:
@@ -1921,7 +1921,7 @@ def _clone_node(node, deep, newOwnerDocument):
19211921
entity.ownerDocument = newOwnerDocument
19221922
clone.entities._seq.append(entity)
19231923
if hasattr(e, '_call_user_data_handler'):
1924-
e._call_user_data_handler(operation, n, entity)
1924+
e._call_user_data_handler(operation, e, entity)
19251925
else:
19261926
# Note the cloning of Document and DocumentType nodes is
19271927
# implementation specific. minidom handles those cases
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix xml.dom.minidom cloneNode() on a document with an entity: pass the
2+
correct arguments to the user data handler of an entity.

0 commit comments

Comments
 (0)