# defusedxml # # Copyright (c) 2013-2020 by Christian Heimes # Licensed to PSF under a Contributor Agreement. # See https://www.python.org/psf/license for licensing details. """Common constants, exceptions and helpe functions """ import sys import xml.parsers.expat PY3 = True # Fail early when pyexpat is not installed correctly if not hasattr(xml.parsers.expat, "ParserCreate"): raise ImportError("pyexpat") # pragma: no cover class DefusedXmlException(ValueError): """Base exception""" def __repr__(self): return str(self) class DTDForbidden(DefusedXmlException): """Document type definition is forbidden""" def __init__(self, name, sysid, pubid): super().__init__() self.name = name self.sysid = sysid self.pubid = pubid def __str__(self): tpl = "DTDForbidden(name='{}', system_id={!r}, public_id={!r})" return tpl.format(self.name, self.sysid, self.pubid) class EntitiesForbidden(DefusedXmlException): """Entity definition is forbidden""" def __init__(self, name, value, base, sysid, pubid, notation_name): super().__init__() self.name = name self.value = value self.base = base self.sysid = sysid self.pubid = pubid self.notation_name = notation_name def __str__(self): tpl = "EntitiesForbidden(name='{}', system_id={!r}, public_id={!r})" return tpl.format(self.name, self.sysid, self.pubid) class ExternalReferenceForbidden(DefusedXmlException): """Resolving an external reference is forbidden""" def __init__(self, context, base, sysid, pubid): super().__init__() self.context = context self.base = base self.sysid = sysid self.pubid = pubid def __str__(self): tpl = "ExternalReferenceForbidden(system_id='{}', public_id={})" return tpl.format(self.sysid, self.pubid) class NotSupportedError(DefusedXmlException): """The operation is not supported""" def _apply_defusing(defused_mod): assert defused_mod is sys.modules[defused_mod.__name__] stdlib_name = defused_mod.__origin__ __import__(stdlib_name, {}, {}, ["*"]) stdlib_mod = sys.modules[stdlib_name] stdlib_names = set(dir(stdlib_mod)) for name, obj in vars(defused_mod).items(): if name.startswith("_") or name not in stdlib_names: continue setattr(stdlib_mod, name, obj) return stdlib_mod