@@ -419,7 +419,7 @@ def test_disable_entities_true_rejects_xmlbomb():
419
419
]>
420
420
<bomb>&c;</bomb>
421
421
"""
422
- with pytest .raises (expat . ExpatError , match = "entities are disabled" ):
422
+ with pytest .raises (ValueError , match = "entities are disabled" ):
423
423
parse (xml , disable_entities = True )
424
424
425
425
@@ -437,39 +437,57 @@ def test_disable_entities_false_returns_xmlbomb():
437
437
assert parse (xml , disable_entities = False ) == expectedResult
438
438
439
439
440
- def test_disable_entities_true_rejects_external_dtd ():
440
+ def test_external_entity ():
441
441
xml = """
442
442
<!DOCTYPE external [
443
443
<!ENTITY ee SYSTEM "http://www.python.org/">
444
444
]>
445
445
<root>ⅇ</root>
446
446
"""
447
- with pytest .raises (expat .ExpatError , match = "entities are disabled" ):
448
- parse (xml , disable_entities = True )
447
+ with pytest .raises (ValueError , match = "entities are disabled" ):
448
+ parse (xml )
449
+ assert parse (xml , disable_entities = False ) == {"root" : None }
449
450
450
451
451
- def test_disable_entities_true_attempts_external_dtd ():
452
+ def test_external_entity_with_custom_expat ():
452
453
xml = """
453
454
<!DOCTYPE external [
454
455
<!ENTITY ee SYSTEM "http://www.python.org/">
455
456
]>
456
457
<root>ⅇ</root>
457
458
"""
458
459
459
- def raising_external_ref_handler (* args , ** kwargs ):
460
- parser = ParserCreate (* args , ** kwargs )
461
- parser .ExternalEntityRefHandler = lambda * x : 0
462
- return parser
463
- expat .ParserCreate = raising_external_ref_handler
464
- # Using this try/catch because a TypeError is thrown before
465
- # the ExpatError.
466
- try :
467
- parse (xml , disable_entities = False , expat = expat )
468
- except expat .ExpatError :
469
- assert True
470
- else :
471
- assert False
472
- expat .ParserCreate = ParserCreate
460
+ class CustomExpat :
461
+ def __init__ (self , external_entity_result ):
462
+ self .external_entity_result = external_entity_result
463
+
464
+ def ParserCreate (self , * args , ** kwargs ):
465
+ parser = ParserCreate (* args , ** kwargs )
466
+
467
+ def _handler (* args , ** kwargs ):
468
+ return self .external_entity_result
469
+
470
+ parser .ExternalEntityRefHandler = _handler
471
+ return parser
472
+
473
+ ExpatError = expat .ExpatError
474
+
475
+ with pytest .raises (expat .ExpatError ):
476
+ parse (xml , disable_entities = False , expat = CustomExpat (0 ))
477
+ assert parse (xml , disable_entities = False , expat = CustomExpat (1 )) == {"root" : None }
478
+ with pytest .raises (ValueError ):
479
+ assert parse (xml , disable_entities = True , expat = CustomExpat (1 ))
480
+ with pytest .raises (ValueError ):
481
+ assert parse (xml , disable_entities = True , expat = CustomExpat (0 ))
482
+
483
+
484
+ def test_disable_entities_true_allows_doctype_without_entities ():
485
+ xml = """<?xml version='1.0' encoding='UTF-8'?>
486
+ <!DOCTYPE data SYSTEM "diagram.dtd">
487
+ <foo>bar</foo>
488
+ """
489
+ assert parse (xml , disable_entities = True ) == {"foo" : "bar" }
490
+ assert parse (xml , disable_entities = False ) == {"foo" : "bar" }
473
491
474
492
475
493
def test_disable_entities_allows_comments_by_default ():
0 commit comments