@@ -1215,9 +1215,10 @@ impl ReverseSuffix {
12151215 ) -> Result < Option < HalfMatch > , RetryError > {
12161216 let mut span = input. get_span ( ) ;
12171217 let mut min_start = 0 ;
1218+ let mut first: Option < HalfMatch > = None ;
12181219 loop {
12191220 let litmatch = match self . pre . find ( input. haystack ( ) , span) {
1220- None => return Ok ( None ) ,
1221+ None => break ,
12211222 Some ( span) => span,
12221223 } ;
12231224 trace ! ( "reverse suffix scan found suffix match at {litmatch:?}" ) ;
@@ -1228,7 +1229,13 @@ impl ReverseSuffix {
12281229 if let Some ( hm) =
12291230 self . try_search_half_rev_limited ( cache, & revinput, min_start) ?
12301231 {
1231- return Ok ( Some ( hm) ) ;
1232+ // We only track the first half-match. We can never find a
1233+ // half-match with lower offset than the first half-match, it
1234+ // would mean quadratic behavior. We can only confirm this
1235+ // half-match or return a quadratic error.
1236+ if first. is_none ( ) {
1237+ first = Some ( hm) ;
1238+ }
12321239 }
12331240
12341241 if span. start >= span. end {
@@ -1237,7 +1244,7 @@ impl ReverseSuffix {
12371244 span. start = litmatch. start . checked_add ( 1 ) . unwrap ( ) ;
12381245 min_start = litmatch. end ;
12391246 }
1240- Ok ( None )
1247+ Ok ( first )
12411248 }
12421249
12431250 #[ cfg_attr( feature = "perf-inline" , inline( always) ) ]
@@ -1623,9 +1630,10 @@ impl ReverseInner {
16231630 let mut span = input. get_span ( ) ;
16241631 let mut min_match_start = 0 ;
16251632 let mut min_pre_start = 0 ;
1633+ let mut first: Option < Match > = None ;
16261634 loop {
16271635 let litmatch = match self . preinner . find ( input. haystack ( ) , span) {
1628- None => return Ok ( None ) ,
1636+ None => break ,
16291637 Some ( span) => span,
16301638 } ;
16311639 if litmatch. start < min_pre_start {
@@ -1662,10 +1670,12 @@ impl ReverseInner {
16621670 span. start = litmatch. start . checked_add ( 1 ) . unwrap ( ) ;
16631671 }
16641672 Ok ( hm_end) => {
1665- return Ok ( Some ( Match :: new (
1666- hm_start. pattern ( ) ,
1667- hm_start. offset ( ) ..hm_end. offset ( ) ,
1668- ) ) )
1673+ if first. is_none ( ) {
1674+ first = Some ( Match :: new (
1675+ hm_start. pattern ( ) ,
1676+ hm_start. offset ( ) ..hm_end. offset ( ) ,
1677+ ) ) ;
1678+ }
16691679 }
16701680 }
16711681 }
@@ -1676,7 +1686,7 @@ impl ReverseInner {
16761686 span. start = litmatch. start . checked_add ( 1 ) . unwrap ( ) ;
16771687 min_match_start = litmatch. end ;
16781688 }
1679- Ok ( None )
1689+ Ok ( first )
16801690 }
16811691
16821692 #[ cfg_attr( feature = "perf-inline" , inline( always) ) ]
0 commit comments