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)