codekingpro/portable-devtools
115k
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"""Defused xml.etree.ElementTree facade7"""8from __future__ import print_function, absolute_import9 10import sys11import warnings12from xml.etree.ElementTree import ParseError13from xml.etree.ElementTree import TreeBuilder as _TreeBuilder14from xml.etree.ElementTree import parse as _parse15from xml.etree.ElementTree import tostring16 17from .common import PY318 19if PY3:20 import importlib21else:22 from xml.etree.ElementTree import XMLParser as _XMLParser23 from xml.etree.ElementTree import iterparse as _iterparse24 25 26from .common import (27 DTDForbidden,28 EntitiesForbidden,29 ExternalReferenceForbidden,30 _generate_etree_functions,31)32 33__origin__ = "xml.etree.ElementTree"34 35 36def _get_py3_cls():37 """Python 3.3 hides the pure Python code but defusedxml requires it.38 39 The code is based on test.support.import_fresh_module().40 """41 pymodname = "xml.etree.ElementTree"42 cmodname = "_elementtree"43 44 pymod = sys.modules.pop(pymodname, None)45 cmod = sys.modules.pop(cmodname, None)46 47 sys.modules[cmodname] = None48 try:49 pure_pymod = importlib.import_module(pymodname)50 finally:51 # restore module52 sys.modules[pymodname] = pymod53 if cmod is not None:54 sys.modules[cmodname] = cmod55 else:56 sys.modules.pop(cmodname, None)57 # restore attribute on original package58 etree_pkg = sys.modules["xml.etree"]59 if pymod is not None:60 etree_pkg.ElementTree = pymod61 elif hasattr(etree_pkg, "ElementTree"):62 del etree_pkg.ElementTree63 64 _XMLParser = pure_pymod.XMLParser65 _iterparse = pure_pymod.iterparse66 # patch pure module to use ParseError from C extension67 pure_pymod.ParseError = ParseError68 69 return _XMLParser, _iterparse70 71 72if PY3:73 _XMLParser, _iterparse = _get_py3_cls()74 75 76_sentinel = object()77 78 79class DefusedXMLParser(_XMLParser):80 def __init__(81 self,82 html=_sentinel,83 target=None,84 encoding=None,85 forbid_dtd=False,86 forbid_entities=True,87 forbid_external=True,88 ):89 # Python 2.x old style class90 _XMLParser.__init__(self, target=target, encoding=encoding)91 if html is not _sentinel:92 # the 'html' argument has been deprecated and ignored in all93 # supported versions of Python. Python 3.8 finally removed it.94 if html:95 raise TypeError("'html=True' is no longer supported.")96 else:97 warnings.warn(98 "'html' keyword argument is no longer supported. Pass "99 "in arguments as keyword arguments.",100 category=DeprecationWarning,101 )102 103 self.forbid_dtd = forbid_dtd104 self.forbid_entities = forbid_entities105 self.forbid_external = forbid_external106 if PY3:107 parser = self.parser108 else:109 parser = self._parser110 if self.forbid_dtd:111 parser.StartDoctypeDeclHandler = self.defused_start_doctype_decl112 if self.forbid_entities:113 parser.EntityDeclHandler = self.defused_entity_decl114 parser.UnparsedEntityDeclHandler = self.defused_unparsed_entity_decl115 if self.forbid_external:116 parser.ExternalEntityRefHandler = self.defused_external_entity_ref_handler117 118 def defused_start_doctype_decl(self, name, sysid, pubid, has_internal_subset):119 raise DTDForbidden(name, sysid, pubid)120 121 def defused_entity_decl(122 self, name, is_parameter_entity, value, base, sysid, pubid, notation_name123 ):124 raise EntitiesForbidden(name, value, base, sysid, pubid, notation_name)125 126 def defused_unparsed_entity_decl(self, name, base, sysid, pubid, notation_name):127 # expat 1.2128 raise EntitiesForbidden(name, None, base, sysid, pubid, notation_name) # pragma: no cover129 130 def defused_external_entity_ref_handler(self, context, base, sysid, pubid):131 raise ExternalReferenceForbidden(context, base, sysid, pubid)132 133 134# aliases135# XMLParse is a typo, keep it for backwards compatibility136XMLTreeBuilder = XMLParse = XMLParser = DefusedXMLParser137 138parse, iterparse, fromstring = _generate_etree_functions(139 DefusedXMLParser, _TreeBuilder, _parse, _iterparse140)141XML = fromstring142 143 144__all__ = [145 "ParseError",146 "XML",147 "XMLParse",148 "XMLParser",149 "XMLTreeBuilder",150 "fromstring",151 "iterparse",152 "parse",153 "tostring",154]155 