@@ -767,13 +767,40 @@ def test_replace(self):
767767 self .checkraises (TypeError , 'hello' , 'replace' , 42 , 'h' )
768768 self .checkraises (TypeError , 'hello' , 'replace' , 'h' , 42 )
769769
770- # gh-127971
770+ def test_replacement_on_buffer_boundary (self ):
771+
772+ # gh-127971: Check we don't read past the end of the buffer when a
773+ # potential match misses on the last character. Note this will likely
774+ # not cause a failure unless ASAN is enabled, and even that may be
775+ # dependent on implementation details subject to change.
771776 any_3_nonblank_codepoints = '!!!'
772777 seven_codepoints = any_3_nonblank_codepoints + ' ' + any_3_nonblank_codepoints
773778 a = (' ' * 243 ) + seven_codepoints + (' ' * 7 )
774779 b = ' ' * 6 + chr (256 )
775780 a .replace (seven_codepoints , b )
776781
782+ def test_adaptive_find_on_buffer_boundary (self ):
783+
784+ # gh-127971: This exercises the adaptive search algorithm to trigger a
785+ # corner-case where it might examine the character *after* the last
786+ # position that could be the start of the pattern.
787+ #
788+ # Unfortunately there is nothing to *test* to confirm whether the
789+ # character is read or not, nor in fact does it matter for correctness
790+ # with the implementation at time of writing: the adaptive algorithm is
791+ # only triggered if the input is over a certain size and with a pattern
792+ # with more than one character, so with the current implementation even
793+ # though the final character read is not necessary or significant, it
794+ # won't cause a fault.
795+ #
796+ # This test at least intentionally exercises this path, and might
797+ # possibly catch a regression if the implementation changes and breaks
798+ # those assumptions.
799+ prefix = ' ' * (1024 * 4 )
800+ haystack = prefix + 'x'
801+ needle = prefix + 'y'
802+ self .assertEqual (haystack .find (needle ), - 1 )
803+
777804 def test_replace_uses_two_way_maxcount (self ):
778805 # Test that maxcount works in _two_way_count in fastsearch.h
779806 A , B = "A" * 1000 , "B" * 1000
0 commit comments