Christian Heimes avatar Christian Heimes committed 7413198

test for cyclic entities

Comments (0)

Files changed (2)

 import re
 
 from xml.sax.saxutils import XMLGenerator
+from xml.sax import SAXParseException
+from pyexpat import ExpatError
 
 from defusedxml import cElementTree, ElementTree, minidom, pulldom, sax
 from defusedxml import (DefusedXmlException, DTDForbidden, EntitiesForbidden,
 
 try:
     from defusedxml import lxml
+    from lxml.etree import XMLSyntaxError
     LXML3 = lxml.LXML3
 except ImportError:
     lxml = None
+    XMLSyntaxError = None
     LXML3 = False
 
 
     dtd_external_ref = False
 
     external_ref_exception = ExternalReferenceForbidden
+    cyclic_error = None
 
     xml_dtd = os.path.join(HERE, "xmltestdata", "dtd.xml")
     xml_external = os.path.join(HERE, "xmltestdata", "external.xml")
     xml_simple_ns = os.path.join(HERE, "xmltestdata", "simple-ns.xml")
     xml_bomb = os.path.join(HERE, "xmltestdata", "xmlbomb.xml")
     xml_bomb2 = os.path.join(HERE, "xmltestdata", "xmlbomb2.xml")
+    xml_cyclic = os.path.join(HERE, "xmltestdata", "cyclic.xml")
 
     if PY26 or PY31:
         # old Python versions don't have these useful test methods
         self.assertRaises(EntitiesForbidden, self.parseString,
                           self.get_content(self.xml_external))
 
+    def test_entity_cycle(self):
+        self.assertRaises(self.cyclic_error, self.parse, self.xml_cyclic,
+                          forbid_entities=False)
+
     def test_dtd_forbidden(self):
         self.assertRaises(DTDForbidden, self.parse, self.xml_bomb,
                           forbid_dtd=True)
 class TestDefusedElementTree(BaseTests):
     module = ElementTree
 
+
     # etree doesn't do external ref lookup
     external_ref_exception = ElementTree.ParseError
 
+    cyclic_error = ElementTree.ParseError
+
     def parse(self, xmlfile, **kwargs):
         tree = self.module.parse(xmlfile, **kwargs)
         return self.module.tostring(tree.getroot())
 class TestDefusedMinidom(BaseTests):
     module = minidom
 
+    cyclic_error = ExpatError
+
+
     iterparse = None
 
     def parse(self, xmlfile, **kwargs):
 class TestDefusedPulldom(BaseTests):
     module = pulldom
 
+    cyclic_error = SAXParseException
+
     dtd_external_ref = True
     iterparse = None
 
 class TestDefusedSax(BaseTests):
     module = sax
 
+    cyclic_error = SAXParseException
+
     content_binary = True
     dtd_external_ref = True
 
 class TestDefusedLxml(BaseTests):
     module = lxml
 
+    cyclic_error = XMLSyntaxError
+
     content_binary = True
     iterparse = None
 

xmltestdata/cyclic.xml

+<!DOCTYPE xmlbomb [
+<!ENTITY a "123 &b;" >
+<!ENTITY b "&a;">
+]>
+<bomb>&a;</bomb>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.