@@ -825,7 +825,7 @@ def start_element(name, _):
825825
826826class AttackProtectionTest (unittest .TestCase ):
827827
828- def billion_laughs (self , ncols , nrows , text = '.' ):
828+ def billion_laughs (self , ncols , nrows , text = '.' , indent = ' ' ):
829829 """Create a billion laugh payload.
830830
831831 Be careful: the number of total items is pow(n, k), thereby
@@ -834,26 +834,28 @@ def billion_laughs(self, ncols, nrows, text='.'):
834834 body = textwrap .indent ('\n ' .join (
835835 f'<!ENTITY row{ i + 1 } "{ f"&row{ i } ;" * ncols } ">'
836836 for i in range (nrows )
837- ), ' ' )
837+ ), indent )
838838 return f"""\
839839 <?xml version="1.0"?>
840840<!DOCTYPE doc [
841- <!ENTITY row0 "{ text } ">
842- <!ELEMENT doc (#PCDATA)>
841+ { indent } <!ENTITY row0 "{ text } ">
842+ { indent } <!ELEMENT doc (#PCDATA)>
843843{ body }
844844]>
845845<doc>&row{ nrows } ;</doc>
846846"""
847847
848848 def test_set_alloc_tracker_maximum_amplification (self ):
849- payload = self .billion_laughs (10 , 4 )
849+ # Run the test with EXPAT_MALLOC_DEBUG=2 to find the max factor.
850+ # The max factor depends on the "indent" and should be above 100.0.
851+ # For this test, the peak amplification factor is 101.71.
852+ payload = self .billion_laughs (1 , 2 )
850853
851854 p = expat .ParserCreate ()
852855 # Unconditionally enable maximum amplification factor.
853856 p .SetAllocTrackerActivationThreshold (0 )
854- # At runtime, the peak amplification factor is 101.71,
855- # which is above the default threshold (100.0).
856- msg = re .escape ("out of memory: line 3, column 15" )
857+ # At runtime, the peak amplification factor is above the default.
858+ msg = r"out of memory: line \d+, column \d+"
857859 self .assertRaisesRegex (expat .ExpatError , msg , p .Parse , payload )
858860
859861 # # Re-create a parser as the current parser is now in an error state.
@@ -894,7 +896,7 @@ def test_set_alloc_tracker_activation_threshold(self):
894896 p .SetAllocTrackerActivationThreshold (MIN_ALLOC - 1 )
895897 # Check that we always reach the activation threshold.
896898 self .assertIsNone (p .SetAllocTrackerMaximumAmplification (1.0 ))
897- msg = re . escape ( "out of memory: line 3 , column 10" )
899+ msg = r "out of memory: line \d+ , column \d+"
898900 self .assertRaisesRegex (expat .ExpatError , msg , p .Parse , payload )
899901
900902 def test_set_alloc_tracker_activation_threshold_invalid_args (self ):
0 commit comments