codekingpro/portable-devtools
114k
1# defusedxml2#3# Copyright (c) 2013 by Christian Heimes <christian@python.org>4# Licensed to PSF under a Contributor Agreement.5# See https://www.python.org/psf/license for licensing details.6"""Common constants, exceptions and helpe functions7"""8import sys9import xml.parsers.expat10 11PY3 = sys.version_info[0] == 312 13# Fail early when pyexpat is not installed correctly14if not hasattr(xml.parsers.expat, "ParserCreate"):15 raise ImportError("pyexpat") # pragma: no cover16 17 18class DefusedXmlException(ValueError):19 """Base exception"""20 21 def __repr__(self):22 return str(self)23 24 25class DTDForbidden(DefusedXmlException):26 """Document type definition is forbidden"""27 28 def __init__(self, name, sysid, pubid):29 super(DTDForbidden, self).__init__()30 self.name = name31 self.sysid = sysid32 self.pubid = pubid33 34 def __str__(self):35 tpl = "DTDForbidden(name='{}', system_id={!r}, public_id={!r})"36 return tpl.format(self.name, self.sysid, self.pubid)37 38 39class EntitiesForbidden(DefusedXmlException):40 """Entity definition is forbidden"""41 42 def __init__(self, name, value, base, sysid, pubid, notation_name):43 super(EntitiesForbidden, self).__init__()44 self.name = name45 self.value = value46 self.base = base47 self.sysid = sysid48 self.pubid = pubid49 self.notation_name = notation_name50 51 def __str__(self):52 tpl = "EntitiesForbidden(name='{}', system_id={!r}, public_id={!r})"53 return tpl.format(self.name, self.sysid, self.pubid)54 55 56class ExternalReferenceForbidden(DefusedXmlException):57 """Resolving an external reference is forbidden"""58 59 def __init__(self, context, base, sysid, pubid):60 super(ExternalReferenceForbidden, self).__init__()61 self.context = context62 self.base = base63 self.sysid = sysid64 self.pubid = pubid65 66 def __str__(self):67 tpl = "ExternalReferenceForbidden(system_id='{}', public_id={})"68 return tpl.format(self.sysid, self.pubid)69 70 71class NotSupportedError(DefusedXmlException):72 """The operation is not supported"""73 74 75def _apply_defusing(defused_mod):76 assert defused_mod is sys.modules[defused_mod.__name__]77 stdlib_name = defused_mod.__origin__78 __import__(stdlib_name, {}, {}, ["*"])79 stdlib_mod = sys.modules[stdlib_name]80 stdlib_names = set(dir(stdlib_mod))81 for name, obj in vars(defused_mod).items():82 if name.startswith("_") or name not in stdlib_names:83 continue84 setattr(stdlib_mod, name, obj)85 return stdlib_mod86 87 88def _generate_etree_functions(DefusedXMLParser, _TreeBuilder, _parse, _iterparse):89 """Factory for functions needed by etree, dependent on whether90 cElementTree or ElementTree is used."""91 92 def parse(source, parser=None, forbid_dtd=False, forbid_entities=True, forbid_external=True):93 if parser is None:94 parser = DefusedXMLParser(95 target=_TreeBuilder(),96 forbid_dtd=forbid_dtd,97 forbid_entities=forbid_entities,98 forbid_external=forbid_external,99 )100 return _parse(source, parser)101 102 def iterparse(103 source,104 events=None,105 parser=None,106 forbid_dtd=False,107 forbid_entities=True,108 forbid_external=True,109 ):110 if parser is None:111 parser = DefusedXMLParser(112 target=_TreeBuilder(),113 forbid_dtd=forbid_dtd,114 forbid_entities=forbid_entities,115 forbid_external=forbid_external,116 )117 return _iterparse(source, events, parser)118 119 def fromstring(text, forbid_dtd=False, forbid_entities=True, forbid_external=True):120 parser = DefusedXMLParser(121 target=_TreeBuilder(),122 forbid_dtd=forbid_dtd,123 forbid_entities=forbid_entities,124 forbid_external=forbid_external,125 )126 parser.feed(text)127 return parser.close()128 129 return parse, iterparse, fromstring130 