bpo-35052: Fix handler on xml.dom.minidom.cloneNode() (GH-11061) (GH-11068)
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 8e04186889
)
This commit is contained in:
parent
324e179009
commit
cecf313d1e
|
@ -3,7 +3,7 @@
|
|||
import copy
|
||||
import pickle
|
||||
from StringIO import StringIO
|
||||
from test.test_support import verbose, run_unittest, findfile
|
||||
from test import support
|
||||
import unittest
|
||||
|
||||
import xml.dom
|
||||
|
@ -14,7 +14,7 @@ from xml.dom.minidom import parse, Node, Document, parseString
|
|||
from xml.dom.minidom import getDOMImplementation
|
||||
|
||||
|
||||
tstfile = findfile("test.xml", subdir="xmltestdata")
|
||||
tstfile = support.findfile("test.xml", subdir="xmltestdata")
|
||||
sample = ("<?xml version='1.0' encoding='us-ascii'?>\n"
|
||||
"<!DOCTYPE doc PUBLIC 'http://xml.python.org/public'"
|
||||
" 'http://xml.python.org/system' [\n"
|
||||
|
@ -711,6 +711,57 @@ class MinidomTest(unittest.TestCase):
|
|||
def testClonePIDeep(self):
|
||||
self.check_clone_pi(1, "testClonePIDeep")
|
||||
|
||||
def check_clone_node_entity(self, clone_document):
|
||||
# bpo-35052: Test user data handler in cloneNode() on a document with
|
||||
# an entity
|
||||
document = xml.dom.minidom.parseString("""
|
||||
<?xml version="1.0" ?>
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
|
||||
"http://www.w3.org/TR/html4/strict.dtd"
|
||||
[ <!ENTITY smile ":-)"> ]
|
||||
>
|
||||
<doc>Don't let entities make you frown ⌣</doc>
|
||||
""".strip())
|
||||
|
||||
class Handler:
|
||||
def handle(self, operation, key, data, src, dst):
|
||||
self.operation = operation
|
||||
self.key = key
|
||||
self.data = data
|
||||
self.src = src
|
||||
self.dst = dst
|
||||
|
||||
handler = Handler()
|
||||
doctype = document.doctype
|
||||
entity = doctype.entities['smile']
|
||||
entity.setUserData("key", "data", handler)
|
||||
|
||||
if clone_document:
|
||||
# clone Document
|
||||
clone = document.cloneNode(deep=True)
|
||||
|
||||
self.assertEqual(clone.documentElement.firstChild.wholeText,
|
||||
"Don't let entities make you frown :-)")
|
||||
operation = xml.dom.UserDataHandler.NODE_IMPORTED
|
||||
dst = clone.doctype.entities['smile']
|
||||
else:
|
||||
# clone DocumentType
|
||||
with support.swap_attr(doctype, 'ownerDocument', None):
|
||||
clone = doctype.cloneNode(deep=True)
|
||||
|
||||
operation = xml.dom.UserDataHandler.NODE_CLONED
|
||||
dst = clone.entities['smile']
|
||||
|
||||
self.assertEqual(handler.operation, operation)
|
||||
self.assertEqual(handler.key, "key")
|
||||
self.assertEqual(handler.data, "data")
|
||||
self.assertIs(handler.src, entity)
|
||||
self.assertIs(handler.dst, dst)
|
||||
|
||||
def testCloneNodeEntity(self):
|
||||
self.check_clone_node_entity(False)
|
||||
self.check_clone_node_entity(True)
|
||||
|
||||
def testNormalize(self):
|
||||
doc = parseString("<doc/>")
|
||||
root = doc.documentElement
|
||||
|
@ -1446,7 +1497,7 @@ class MinidomTest(unittest.TestCase):
|
|||
|
||||
|
||||
def test_main():
|
||||
run_unittest(MinidomTest)
|
||||
support.run_unittest(MinidomTest)
|
||||
|
||||
if __name__ == "__main__":
|
||||
test_main()
|
||||
|
|
|
@ -1273,7 +1273,7 @@ class DocumentType(Identified, Childless, Node):
|
|||
entity.encoding = e.encoding
|
||||
entity.version = e.version
|
||||
clone.entities._seq.append(entity)
|
||||
e._call_user_data_handler(operation, n, entity)
|
||||
e._call_user_data_handler(operation, e, entity)
|
||||
self._call_user_data_handler(operation, self, clone)
|
||||
return clone
|
||||
else:
|
||||
|
@ -1876,7 +1876,7 @@ def _clone_node(node, deep, newOwnerDocument):
|
|||
entity.ownerDocument = newOwnerDocument
|
||||
clone.entities._seq.append(entity)
|
||||
if hasattr(e, '_call_user_data_handler'):
|
||||
e._call_user_data_handler(operation, n, entity)
|
||||
e._call_user_data_handler(operation, e, entity)
|
||||
else:
|
||||
# Note the cloning of Document and DocumentType nodes is
|
||||
# implementation specific. minidom handles those cases
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
Fix xml.dom.minidom cloneNode() on a document with an entity: pass the
|
||||
correct arguments to the user data handler of an entity.
|
Loading…
Reference in New Issue