summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES.txt11
-rw-r--r--README.txt33
-rw-r--r--tests.py60
3 files changed, 78 insertions, 26 deletions
diff --git a/CHANGES.txt b/CHANGES.txt
index e8d90d7..6bb87cb 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -6,11 +6,14 @@ defusedxml 0.2
*Release date: ??-Feb-2013*
-- Renamed ExternalEntitiesForbidden to ExternalReferenceForbidden
-- Renamed defusedxml.lxml.check_dtd() to check_docinfo()
-- Unified argument names in callbacks
-- Added arguments and formatted representation to exceptions
+- Rename ExternalEntitiesForbidden to ExternalReferenceForbidden
+- Rename defusedxml.lxml.check_dtd() to check_docinfo()
+- Unify argument names in callbacks
+- Add arguments and formatted representation to exceptions
+- Add forbid_external argument to all functions and classs
- More tests
+- LOTS of documentation
+- Add example code for other languages (Ruby, Perl, PHP) and parsers (Genshi)
defusedxml 0.1
--------------
diff --git a/README.txt b/README.txt
index 2612a45..2dad36e 100644
--- a/README.txt
+++ b/README.txt
@@ -176,19 +176,20 @@ Python XML Libraries
====================
.. csv-table::
- :header: "kind", "sax", "etree", "minidom", "pulldom", "lxml", "genshi"
- :widths: 24, 8, 8, 8, 8, 8, 8
-
- "billion laughs", "True", "True", "True", "True", "False (1)", "False (5)"
- "quadratic blowup", "True", "True", "True", "True", "True", "False (5)"
- "external entity expansion (remote)", "True", "False (3)", "False (4)", "True", "False (1)", "False (5)"
- "external entity expansion (local file)", "True", "False (3)", "False (4)", "True", "True", "False (5)"
- "DTD retrieval", "True", "False", "False", "True", "False (1)", "False"
- "gzip bomb", "False", "False", "False", "False", "partly (2)", "False"
- "xpath support", "False", "False", "False", "False", "True", "False"
- "xsl(t) support", "False", "False", "False", "False", "True", "False"
- "xinclude support", "False", "True (6)", "False", "False", "True (6)", "True"
- "C library", "expat", "expat", "expat", "expat", "libxml2", "expat"
+ :header: "kind", "sax", "etree", "minidom", "pulldom", "xmlrpc", "lxml", "genshi"
+ :widths: 24, 7, 8, 8, 7, 8, 8, 8
+ :stub-columns: 0
+
+ "billion laughs", "**True**", "**True**", "**True**", "**True**", "**True**", "False (1)", "False (5)"
+ "quadratic blowup", "**True**", "**True**", "**True**", "**True**", "**True**", "**True**", "False (5)"
+ "external entity expansion (remote)", "**True**", "False (3)", "False (4)", "**True**", "untested", "False (1)", "False (5)"
+ "external entity expansion (local file)", "**True**", "False (3)", "False (4)", "**True**", "untested", "**True**", "False (5)"
+ "DTD retrieval", "**True**", "False", "False", "**True**", "untested", "False (1)", "False"
+ "gzip bomb", "False", "False", "False", "False", "**True**", "**partly** (2)", "False"
+ "xpath support", "False", "False", "False", "False", "False", "**True**", "False"
+ "xsl(t) support", "False", "False", "False", "False", "False", "**True**", "False"
+ "xinclude support", "False", "**True** (6)", "False", "False", "False", "**True** (6)", "**True**"
+ "C library", "expat", "expat", "expat", "expat", "expat", "libxml2", "expat"
1. Lxml is protected against billion laughs attacks and doesn't do network
lookups by default.
@@ -275,6 +276,11 @@ defused.pulldom
parse(), parseString()
+defused.xmlrpclib
+-----------------
+
+TODO
+
defused.lxml
------------
@@ -506,6 +512,7 @@ TODO
* SAX: take feature_external_ges and feature_external_pes (?) into account
* implement monkey patching of stdlib modules
* document which module / library is vulnerable to which kind of attack
+* Add fix for xmlrpc's ExpatParser
* documentation, documentation, documentation ...
diff --git a/tests.py b/tests.py
index 8f7ff14..ae2ba6a 100644
--- a/tests.py
+++ b/tests.py
@@ -14,6 +14,10 @@ from defusedxml import (DefusedXmlException, DTDForbidden, EntitiesForbidden,
ExternalReferenceForbidden, NotSupportedError)
from defusedxml.common import PY3, PY26, PY31
+if PY3:
+ from xmlrpclib.client import ExpatParser as XmlRpcParser
+else:
+ from xmlrpclib import ExpatParser as XmlRpcParser
try:
from defusedxml import lxml
@@ -67,19 +71,13 @@ if PY26 or PY31:
return True
-class BaseTests(unittest.TestCase):
- module = None
+class DefusedTestCase(unittest.TestCase):
if PY3:
content_binary = False
else:
content_binary = True
- 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_external_file = os.path.join(HERE, "xmltestdata", "external_file.xml")
@@ -111,6 +109,15 @@ class BaseTests(unittest.TestCase):
data = f.read()
return data
+
+class BaseTests(DefusedTestCase):
+ module = None
+ dtd_external_ref = False
+
+ external_ref_exception = ExternalReferenceForbidden
+ cyclic_error = None
+
+
def test_simple_parse(self):
self.parse(self.xml_simple)
self.parseString(self.get_content(self.xml_simple))
@@ -193,8 +200,8 @@ class TestDefusedElementTree(BaseTests):
module = ElementTree
- # etree doesn't do external ref lookup
- external_ref_exception = ElementTree.ParseError
+ ## etree doesn't do external ref lookup
+ #external_ref_exception = ElementTree.ParseError
cyclic_error = ElementTree.ParseError
@@ -391,6 +398,40 @@ class TestDefusedLxml(BaseTests):
self.assertEqual(elements, list(root)[:1])
+class XmlRpcTarget(object):
+ def __init__(self):
+ self._data = []
+
+ def __str__(self):
+ return "\n".join(self._data)
+
+ def xml(self, encoding, standalone):
+ pass
+
+ def start(self, tag, attrs):
+ self._data.append("<%s>" % tag)
+
+ def data(self, text):
+ self._data.append(text)
+
+ def end(self, tag):
+ self._data.append("</%s>" % tag)
+
+
+class TestXmlRpc(DefusedTestCase):
+ def parse(self, xmlfile):
+ target = XmlRpcTarget()
+ parser = XmlRpcParser(target)
+ data = self.get_content(xmlfile)
+ parser.feed(data)
+ parser.close()
+ return target
+
+ def test_xmlrpc(self):
+ self.parse(self.xml_bomb)
+ self.parse(self.xml_quadratic)
+
+
def test_main():
suite = unittest.TestSuite()
suite.addTests(unittest.makeSuite(TestDefusedcElementTree))
@@ -398,6 +439,7 @@ def test_main():
suite.addTests(unittest.makeSuite(TestDefusedMinidom))
suite.addTests(unittest.makeSuite(TestDefusedPulldom))
suite.addTests(unittest.makeSuite(TestDefusedSax))
+ suite.addTests(unittest.makeSuite(TestXmlRpc))
if lxml is not None:
suite.addTests(unittest.makeSuite(TestDefusedLxml))
return suite