Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/defusedxml/expatbuilder.py: 70%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

54 statements  

1# defusedxml 

2# 

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.dom.expatbuilder 

7""" 

8from __future__ import print_function, absolute_import 

9 

10from xml.dom.expatbuilder import ExpatBuilder as _ExpatBuilder 

11from xml.dom.expatbuilder import Namespaces as _Namespaces 

12 

13from .common import DTDForbidden, EntitiesForbidden, ExternalReferenceForbidden 

14 

15__origin__ = "xml.dom.expatbuilder" 

16 

17 

18class DefusedExpatBuilder(_ExpatBuilder): 

19 """Defused document builder""" 

20 

21 def __init__( 

22 self, options=None, forbid_dtd=False, forbid_entities=True, forbid_external=True 

23 ): 

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, has_internal_subset): 

30 raise DTDForbidden(name, sysid, pubid) 

31 

32 def defused_entity_decl( 

33 self, name, is_parameter_entity, value, base, sysid, pubid, notation_name 

34 ): 

35 raise EntitiesForbidden(name, value, base, sysid, pubid, notation_name) 

36 

37 def defused_unparsed_entity_decl(self, name, base, sysid, pubid, notation_name): 

38 # expat 1.2 

39 raise EntitiesForbidden(name, None, base, sysid, pubid, notation_name) # pragma: no cover 

40 

41 def defused_external_entity_ref_handler(self, context, base, sysid, pubid): 

42 raise ExternalReferenceForbidden(context, base, sysid, pubid) 

43 

44 def install(self, parser): 

45 _ExpatBuilder.install(self, parser) 

46 

47 if self.forbid_dtd: 

48 parser.StartDoctypeDeclHandler = self.defused_start_doctype_decl 

49 if self.forbid_entities: 

50 # if self._options.entities: 

51 parser.EntityDeclHandler = self.defused_entity_decl 

52 parser.UnparsedEntityDeclHandler = self.defused_unparsed_entity_decl 

53 if self.forbid_external: 

54 parser.ExternalEntityRefHandler = self.defused_external_entity_ref_handler 

55 

56 

57class DefusedExpatBuilderNS(_Namespaces, DefusedExpatBuilder): 

58 """Defused document builder that supports namespaces.""" 

59 

60 def install(self, parser): 

61 DefusedExpatBuilder.install(self, parser) 

62 if self._options.namespace_declarations: 

63 parser.StartNamespaceDeclHandler = self.start_namespace_decl_handler 

64 

65 def reset(self): 

66 DefusedExpatBuilder.reset(self) 

67 self._initNamespaces() 

68 

69 

70def parse(file, namespaces=True, forbid_dtd=False, forbid_entities=True, forbid_external=True): 

71 """Parse a document, returning the resulting Document node. 

72 

73 'file' may be either a file name or an open file object. 

74 """ 

75 if namespaces: 

76 build_builder = DefusedExpatBuilderNS 

77 else: 

78 build_builder = DefusedExpatBuilder 

79 builder = build_builder( 

80 forbid_dtd=forbid_dtd, forbid_entities=forbid_entities, forbid_external=forbid_external 

81 ) 

82 

83 if isinstance(file, str): 

84 fp = open(file, "rb") 

85 try: 

86 result = builder.parseFile(fp) 

87 finally: 

88 fp.close() 

89 else: 

90 result = builder.parseFile(file) 

91 return result 

92 

93 

94def parseString( 

95 string, namespaces=True, forbid_dtd=False, forbid_entities=True, forbid_external=True 

96): 

97 """Parse a document from a string, returning the resulting 

98 Document node. 

99 """ 

100 if namespaces: 

101 build_builder = DefusedExpatBuilderNS 

102 else: 

103 build_builder = DefusedExpatBuilder 

104 builder = build_builder( 

105 forbid_dtd=forbid_dtd, forbid_entities=forbid_entities, forbid_external=forbid_external 

106 ) 

107 return builder.parseString(string)