github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/gubernator/third_party/defusedxml/common.py (about) 1 # defusedxml 2 # 3 # Copyright (c) 2013 by Christian Heimes <christian@python.org> 4 # Licensed to PSF under a Contributor Agreement. 5 # See http://www.python.org/psf/license for licensing details. 6 """Common constants, exceptions and helpe functions 7 """ 8 import sys 9 from types import MethodType 10 11 PY3 = sys.version_info[0] == 3 12 PY26 = sys.version_info[:2] == (2, 6) 13 PY31 = sys.version_info[:2] == (3, 1) 14 15 16 class DefusedXmlException(ValueError): 17 """Base exception 18 """ 19 def __repr__(self): 20 return str(self) 21 22 23 class DTDForbidden(DefusedXmlException): 24 """Document type definition is forbidden 25 """ 26 def __init__(self, name, sysid, pubid): 27 super(DTDForbidden, self).__init__() 28 self.name = name 29 self.sysid = sysid 30 self.pubid = pubid 31 32 def __str__(self): 33 tpl = "DTDForbidden(name='{}', system_id={!r}, public_id={!r})" 34 return tpl.format(self.name, self.sysid, self.pubid) 35 36 37 class EntitiesForbidden(DefusedXmlException): 38 """Entity definition is forbidden 39 """ 40 def __init__(self, name, value, base, sysid, pubid, notation_name): 41 super(EntitiesForbidden, self).__init__() 42 self.name = name 43 self.value = value 44 self.base = base 45 self.sysid = sysid 46 self.pubid = pubid 47 self.notation_name = notation_name 48 49 def __str__(self): 50 tpl = "EntitiesForbidden(name='{}', system_id={!r}, public_id={!r})" 51 return tpl.format(self.name, self.sysid, self.pubid) 52 53 54 class ExternalReferenceForbidden(DefusedXmlException): 55 """Resolving an external reference is forbidden 56 """ 57 def __init__(self, context, base, sysid, pubid): 58 super(ExternalReferenceForbidden, self).__init__() 59 self.context = context 60 self.base = base 61 self.sysid = sysid 62 self.pubid = pubid 63 64 def __str__(self): 65 tpl = "ExternalReferenceForbidden(system_id='{}', public_id={})" 66 return tpl.format(self.sysid, self.pubid) 67 68 69 class NotSupportedError(DefusedXmlException): 70 """The operation is not supported 71 """ 72 73 74 def _apply_defusing(defused_mod): 75 assert defused_mod is sys.modules[defused_mod.__name__] 76 stdlib_name = defused_mod.__origin__ 77 __import__(stdlib_name, {}, {}, ["*"]) 78 stdlib_mod = sys.modules[stdlib_name] 79 stdlib_names = set(dir(stdlib_mod)) 80 for name, obj in vars(defused_mod).items(): 81 if name.startswith("_") or name not in stdlib_names: 82 continue 83 setattr(stdlib_mod, name, obj) 84 return stdlib_mod 85 86 87 def _generate_etree_functions(DefusedXMLParser, _TreeBuilder, 88 _IterParseIterator, _parse, _iterparse): 89 """Factory for functions needed by etree, dependent on whether 90 cElementTree or ElementTree is used.""" 91 92 def parse(source, parser=None, forbid_dtd=False, forbid_entities=True, 93 forbid_external=True): 94 if parser is None: 95 parser = DefusedXMLParser(target=_TreeBuilder(), 96 forbid_dtd=forbid_dtd, 97 forbid_entities=forbid_entities, 98 forbid_external=forbid_external) 99 return _parse(source, parser) 100 101 if PY26 or PY31: 102 def bind(xmlparser, funcname, hookname): 103 func = getattr(DefusedXMLParser, funcname) 104 if PY26: 105 # unbound -> function 106 func = func.__func__ 107 method = MethodType(func, xmlparser, xmlparser.__class__) 108 else: 109 method = MethodType(func, xmlparser) 110 # set hook 111 setattr(xmlparser._parser, hookname, method) 112 113 def iterparse(source, events=None, forbid_dtd=False, 114 forbid_entities=True, forbid_external=True): 115 it = _iterparse(source, events) 116 xmlparser = it._parser 117 if forbid_dtd: 118 bind(xmlparser, "defused_start_doctype_decl", 119 "StartDoctypeDeclHandler") 120 if forbid_entities: 121 bind(xmlparser, "defused_entity_decl", 122 "EntityDeclHandler") 123 bind(xmlparser, "defused_unparsed_entity_decl", 124 "UnparsedEntityDeclHandler") 125 if forbid_external: 126 bind(xmlparser, "defused_external_entity_ref_handler", 127 "ExternalEntityRefHandler") 128 return it 129 elif PY3: 130 def iterparse(source, events=None, parser=None, forbid_dtd=False, 131 forbid_entities=True, forbid_external=True): 132 close_source = False 133 if not hasattr(source, "read"): 134 source = open(source, "rb") 135 close_source = True 136 if not parser: 137 parser = DefusedXMLParser(target=_TreeBuilder(), 138 forbid_dtd=forbid_dtd, 139 forbid_entities=forbid_entities, 140 forbid_external=forbid_external) 141 return _IterParseIterator(source, events, parser, close_source) 142 else: 143 # Python 2.7 144 def iterparse(source, events=None, parser=None, forbid_dtd=False, 145 forbid_entities=True, forbid_external=True): 146 if parser is None: 147 parser = DefusedXMLParser(target=_TreeBuilder(), 148 forbid_dtd=forbid_dtd, 149 forbid_entities=forbid_entities, 150 forbid_external=forbid_external) 151 return _iterparse(source, events, parser) 152 153 def fromstring(text, forbid_dtd=False, forbid_entities=True, 154 forbid_external=True): 155 parser = DefusedXMLParser(target=_TreeBuilder(), 156 forbid_dtd=forbid_dtd, 157 forbid_entities=forbid_entities, 158 forbid_external=forbid_external) 159 parser.feed(text) 160 return parser.close() 161 162 163 return parse, iterparse, fromstring