Skip to content

Commit 3fd9755

Browse files
vstinnerstratakisencukou
authored
bpo-35052: Fix handler on xml.dom.minidom.cloneNode() (GH-11061) (GH-11067)
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 <[email protected]> Co-Authored-By: Petr Viktorin <[email protected]> (cherry picked from commit 8e04186)
1 parent f2d2cb1 commit 3fd9755

File tree

3 files changed

+57
-4
lines changed

3 files changed

+57
-4
lines changed

‎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"
@@ -846,6 +846,57 @@ def testClonePIShallow(self):
846846
def testClonePIDeep(self):
847847
self.check_clone_pi(1, "testClonePIDeep")
848848

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