File tree Expand file tree Collapse file tree
Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -616,6 +616,15 @@ def test_stack_overflow(self):
616616 self .assertEqual (re .match ('(x)*y' , 50000 * 'x' + 'y' ).group (1 ), 'x' )
617617 self .assertEqual (re .match ('(x)*?y' , 50000 * 'x' + 'y' ).group (1 ), 'x' )
618618
619+ def test_unlimited_zero_width_repeat (self ):
620+ # Issue #9669
621+ self .assertIsNone (re .match (r'(?:a?)*y' , 'z' ))
622+ self .assertIsNone (re .match (r'(?:a?)+y' , 'z' ))
623+ self .assertIsNone (re .match (r'(?:a?){2,}y' , 'z' ))
624+ self .assertIsNone (re .match (r'(?:a?)*?y' , 'z' ))
625+ self .assertIsNone (re .match (r'(?:a?)+?y' , 'z' ))
626+ self .assertIsNone (re .match (r'(?:a?){2,}?y' , 'z' ))
627+
619628 def test_scanner (self ):
620629 def s_ident (scanner , token ): return token
621630 def s_operator (scanner , token ): return "op%s" % token
Original file line number Diff line number Diff line change @@ -224,6 +224,9 @@ Core and Builtins
224224Library
225225-------
226226
227+ - Issue #9669: Protect re against infinite loops on zero-width matching in
228+ non-greedy repeat. Patch by Matthew Barnett.
229+
227230- Issue #13169: The maximal repetition number in a regular expression has been
228231 increased from 65534 to 2147483647 (on 32-bit platform) or 4294967294 (on
229232 64-bit).
Original file line number Diff line number Diff line change @@ -1295,13 +1295,18 @@ SRE_MATCH(SRE_STATE* state, SRE_CODE* pattern)
12951295
12961296 LASTMARK_RESTORE ();
12971297
1298- if (ctx -> count >= ctx -> u .rep -> pattern [2 ]
1299- && ctx -> u .rep -> pattern [2 ] != SRE_MAXREPEAT )
1298+ if ((ctx -> count >= ctx -> u .rep -> pattern [2 ]
1299+ && ctx -> u .rep -> pattern [2 ] != SRE_MAXREPEAT ) ||
1300+ state -> ptr == ctx -> u .rep -> last_ptr )
13001301 RETURN_FAILURE ;
13011302
13021303 ctx -> u .rep -> count = ctx -> count ;
1304+ /* zero-width match protection */
1305+ DATA_PUSH (& ctx -> u .rep -> last_ptr );
1306+ ctx -> u .rep -> last_ptr = state -> ptr ;
13031307 DO_JUMP (JUMP_MIN_UNTIL_3 ,jump_min_until_3 ,
13041308 ctx -> u .rep -> pattern + 3 );
1309+ DATA_POP (& ctx -> u .rep -> last_ptr );
13051310 if (ret ) {
13061311 RETURN_ON_ERROR (ret );
13071312 RETURN_SUCCESS ;
You can’t perform that action at this time.
0 commit comments