Skip to content

Commit ca902fb

Browse files
committed
Fix Issue #17372 - Deal with NOTHING regops in trie code properly
We weren't handling NOTHING regops that were not followed by a trieable type in the trie code.
1 parent 1b173b1 commit ca902fb

File tree

2 files changed

+26
-2
lines changed

2 files changed

+26
-2
lines changed

regcomp.c

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2797,7 +2797,12 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
27972797
if (OP(noper) == NOTHING) {
27982798
/* skip past a NOTHING at the start of an alternation
27992799
* eg, /(?:)a|(?:b)/ should be the same as /a|b/
2800+
*
2801+
* If the next node is not something we are supposed to process
2802+
* we will just ignore it due to the condition guarding the
2803+
* next block.
28002804
*/
2805+
28012806
regnode *noper_next= regnext(noper);
28022807
if (noper_next < tail)
28032808
noper= noper_next;
@@ -3019,6 +3024,9 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
30193024
regnode *noper_next= regnext(noper);
30203025
if (noper_next < tail)
30213026
noper= noper_next;
3027+
/* we will undo this assignment if noper does not
3028+
* point at a trieable type in the else clause of
3029+
* the following statement. */
30223030
}
30233031

30243032
if ( noper < tail
@@ -3080,7 +3088,13 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
30803088
Perl_croak( aTHX_ "panic! In trie construction, no char mapping for %" IVdf, uvc );
30813089
}
30823090
}
3083-
}
3091+
} else {
3092+
/* If we end up here it is because we skipped past a NOTHING, but did not end up
3093+
* on a trieable type. So we need to reset noper back to point at the first regop
3094+
* in the branch before we call TRIE_HANDLE_WORD()
3095+
*/
3096+
noper= NEXTOPER(cur);
3097+
}
30843098
TRIE_HANDLE_WORD(state);
30853099

30863100
} /* end second pass */
@@ -3244,6 +3258,9 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
32443258
regnode *noper_next= regnext(noper);
32453259
if (noper_next < tail)
32463260
noper= noper_next;
3261+
/* we will undo this assignment if noper does not
3262+
* point at a trieable type in the else clause of
3263+
* the following statement. */
32473264
}
32483265

32493266
if ( noper < tail
@@ -3284,6 +3301,12 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch,
32843301
/* charid is now 0 if we dont know the char read, or
32853302
* nonzero if we do */
32863303
}
3304+
} else {
3305+
/* If we end up here it is because we skipped past a NOTHING, but did not end up
3306+
* on a trieable type. So we need to reset noper back to point at the first regop
3307+
* in the branch before we call TRIE_HANDLE_WORD().
3308+
*/
3309+
noper= NEXTOPER(cur);
32873310
}
32883311
accept_state = TRIE_NODENUM( state );
32893312
TRIE_HANDLE_WORD(accept_state);

t/re/re_tests

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2017,6 +2017,7 @@ AB\s+\x{100} AB \x{100}X y - -
20172017
/(?iu)(?<=\xdf)hbase/ sshbase y $& hbase
20182018
/\x{30c3}?[\x{30a2}\x{30a4}\x{30a6}\x{30a8}\x{30aa}-\x{30e2}\x{30e4}\x{30e6}\x{30e8}-\x{30f4}](?:[\x{30e3}\x{30e5}\x{30e7}\x{30a1}\x{30a3}\x{30a5}\x{30a7}\x{30a9}])?\x{30fc}?\x{30f3}?/ \x{30de}\x{30fc}\x{30af}\x{30b5}\x{30fc}\x{30d3}\x{30b9} y $& \x{30de}\x{30fc} # part of [perl #133942
20192019
/[\x{3041}-\x{3093}]+/ \x{6f22}\x{5b57}\x{3001}\x{30ab}\x{30bf}\x{30ab}\x{30ca}\x{3001}\x{3072}\x{3089}\x{304c}\x{306a}\x{306e}\x{5165}\x{3063}\x{305f}String y $& \x{3072}\x{3089}\x{304c}\x{306a}\x{306e} # [perl #133978]
2020-
2020+
/(?:0)|(?:)(?:[1-9])/ q0 y $& 0 # [https://github.com/Perl/perl5/issues/17372]
20212021
# Keep these lines at the end of the file
2022+
# pat string y/n/etc expr expected-expr skip-reason comment
20222023
# vim: softtabstop=0 noexpandtab

0 commit comments

Comments
 (0)