@@ -64,6 +64,23 @@ def test_issue7820(self):
6464 # two bytes in common with the UTF-8 BOM
6565 self .assertRaises (SyntaxError , eval , b'\xef \xbb \x20 ' )
6666
67+ def test_truncated_utf8_at_eof (self ):
68+ # Regression test for https://issues.oss-fuzz.com/issues/451112368
69+ # Truncated multi-byte UTF-8 sequences at end of input caused an
70+ # out-of-bounds read in Parser/tokenizer/helpers.c:valid_utf8().
71+ truncated = [
72+ b'\xc2 ' , # 2-byte lead, missing 1 continuation
73+ b'\xdf ' , # 2-byte lead, missing 1 continuation
74+ b'\xe0 ' , # 3-byte lead, missing 2 continuations
75+ b'\xe0 \xa0 ' , # 3-byte lead, missing 1 continuation
76+ b'\xf0 \x90 ' , # 4-byte lead, missing 2 continuations
77+ b'\xf0 \x90 \x80 ' , # 4-byte lead, missing 1 continuation
78+ b'\xf3 ' , # 4-byte lead, missing 3 (the oss-fuzz reproducer)
79+ ]
80+ for seq in truncated :
81+ with self .subTest (seq = seq ):
82+ self .assertRaises (SyntaxError , compile , seq , '<test>' , 'exec' )
83+
6784 @requires_subprocess ()
6885 def test_20731 (self ):
6986 sub = subprocess .Popen ([sys .executable ,
0 commit comments