github.com/munnerz/test-infra@v0.0.0-20190108210205-ce3d181dc989/gubernator/third_party/defusedxml/expatbuilder.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 """Defused xml.dom.expatbuilder 7 """ 8 from __future__ import print_function, absolute_import 9 10 from xml.dom.expatbuilder import ExpatBuilder as _ExpatBuilder 11 from xml.dom.expatbuilder import Namespaces as _Namespaces 12 13 from .common import (DTDForbidden, EntitiesForbidden, 14 ExternalReferenceForbidden) 15 16 __origin__ = "xml.dom.expatbuilder" 17 18 19 class DefusedExpatBuilder(_ExpatBuilder): 20 """Defused document builder""" 21 22 def __init__(self, options=None, forbid_dtd=False, forbid_entities=True, 23 forbid_external=True): 24 _ExpatBuilder.__init__(self, options) 25 self.forbid_dtd = forbid_dtd 26 self.forbid_entities = forbid_entities 27 self.forbid_external = forbid_external 28 29 def defused_start_doctype_decl(self, name, sysid, pubid, 30 has_internal_subset): 31 raise DTDForbidden(name, sysid, pubid) 32 33 def defused_entity_decl(self, name, is_parameter_entity, value, base, 34 sysid, pubid, notation_name): 35 raise EntitiesForbidden(name, value, base, sysid, pubid, notation_name) 36 37 def defused_unparsed_entity_decl(self, name, base, sysid, pubid, 38 notation_name): 39 # expat 1.2 40 raise EntitiesForbidden(name, None, base, sysid, pubid, notation_name) 41 42 def defused_external_entity_ref_handler(self, context, base, sysid, 43 pubid): 44 raise ExternalReferenceForbidden(context, base, sysid, pubid) 45 46 def install(self, parser): 47 _ExpatBuilder.install(self, parser) 48 49 if self.forbid_dtd: 50 parser.StartDoctypeDeclHandler = self.defused_start_doctype_decl 51 if self.forbid_entities: 52 #if self._options.entities: 53 parser.EntityDeclHandler = self.defused_entity_decl 54 parser.UnparsedEntityDeclHandler = self.defused_unparsed_entity_decl 55 if self.forbid_external: 56 parser.ExternalEntityRefHandler = self.defused_external_entity_ref_handler 57 58 59 class DefusedExpatBuilderNS(_Namespaces, DefusedExpatBuilder): 60 """Defused document builder that supports namespaces.""" 61 62 def install(self, parser): 63 DefusedExpatBuilder.install(self, parser) 64 if self._options.namespace_declarations: 65 parser.StartNamespaceDeclHandler = ( 66 self.start_namespace_decl_handler) 67 68 def reset(self): 69 DefusedExpatBuilder.reset(self) 70 self._initNamespaces() 71 72 73 def parse(file, namespaces=True, forbid_dtd=False, forbid_entities=True, 74 forbid_external=True): 75 """Parse a document, returning the resulting Document node. 76 77 'file' may be either a file name or an open file object. 78 """ 79 if namespaces: 80 build_builder = DefusedExpatBuilderNS 81 else: 82 build_builder = DefusedExpatBuilder 83 builder = build_builder(forbid_dtd=forbid_dtd, 84 forbid_entities=forbid_entities, 85 forbid_external=forbid_external) 86 87 if isinstance(file, str): 88 fp = open(file, 'rb') 89 try: 90 result = builder.parseFile(fp) 91 finally: 92 fp.close() 93 else: 94 result = builder.parseFile(file) 95 return result 96 97 98 def parseString(string, namespaces=True, forbid_dtd=False, 99 forbid_entities=True, forbid_external=True): 100 """Parse a document from a string, returning the resulting 101 Document node. 102 """ 103 if namespaces: 104 build_builder = DefusedExpatBuilderNS 105 else: 106 build_builder = DefusedExpatBuilder 107 builder = build_builder(forbid_dtd=forbid_dtd, 108 forbid_entities=forbid_entities, 109 forbid_external=forbid_external) 110 return builder.parseString(string)