diff options
author | Yves Orton <demerphq@gmail.com> | 2020-01-09 15:36:41 +0100 |
---|---|---|
committer | Steve Hay <steve.m.hay@googlemail.com> | 2020-02-12 17:57:17 +0000 |
commit | 3df4e022c7c354ad55f2ee5e104feeb180a23196 (patch) | |
tree | 9f16716075a2e6f0dbfbb667d245d62a832c6629 | |
parent | 818b850a7d83272f593d35f86a9263ec4e83dcb1 (diff) | |
download | perl-3df4e022c7c354ad55f2ee5e104feeb180a23196.tar.gz |
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.
(cherry picked from commit ca902fb80835be4a725df117917a4b62cc7022fe)
-rw-r--r-- | regcomp.c | 25 | ||||
-rw-r--r-- | t/re/re_tests | 3 |
2 files changed, 26 insertions, 2 deletions
@@ -2769,7 +2769,12 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, if (OP(noper) == NOTHING) { /* skip past a NOTHING at the start of an alternation * eg, /(?:)a|(?:b)/ should be the same as /a|b/ + * + * If the next node is not something we are supposed to process + * we will just ignore it due to the condition guarding the + * next block. */ + regnode *noper_next= regnext(noper); if (noper_next < tail) noper= noper_next; @@ -2991,6 +2996,9 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *noper_next= regnext(noper); if (noper_next < tail) noper= noper_next; + /* we will undo this assignment if noper does not + * point at a trieable type in the else clause of + * the following statement. */ } if ( noper < tail @@ -3052,7 +3060,13 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, Perl_croak( aTHX_ "panic! In trie construction, no char mapping for %" IVdf, uvc ); } } - } + } else { + /* If we end up here it is because we skipped past a NOTHING, but did not end up + * on a trieable type. So we need to reset noper back to point at the first regop + * in the branch before we call TRIE_HANDLE_WORD() + */ + noper= NEXTOPER(cur); + } TRIE_HANDLE_WORD(state); } /* end second pass */ @@ -3216,6 +3230,9 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, regnode *noper_next= regnext(noper); if (noper_next < tail) noper= noper_next; + /* we will undo this assignment if noper does not + * point at a trieable type in the else clause of + * the following statement. */ } if ( noper < tail @@ -3256,6 +3273,12 @@ S_make_trie(pTHX_ RExC_state_t *pRExC_state, regnode *startbranch, /* charid is now 0 if we dont know the char read, or * nonzero if we do */ } + } else { + /* If we end up here it is because we skipped past a NOTHING, but did not end up + * on a trieable type. So we need to reset noper back to point at the first regop + * in the branch before we call TRIE_HANDLE_WORD(). + */ + noper= NEXTOPER(cur); } accept_state = TRIE_NODENUM( state ); TRIE_HANDLE_WORD(accept_state); diff --git a/t/re/re_tests b/t/re/re_tests index 17a5b53eee..d07c94381d 100644 --- a/t/re/re_tests +++ b/t/re/re_tests @@ -2016,6 +2016,7 @@ AB\s+\x{100} AB \x{100}X y - - /(?iu)(?<=\xdf)hbase/ sshbase y $& hbase /\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 /[\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] - +/(?:0)|(?:)(?:[1-9])/ q0 y $& 0 # [https://github.com/Perl/perl5/issues/17372] # Keep these lines at the end of the file +# pat string y/n/etc expr expected-expr skip-reason comment # vim: softtabstop=0 noexpandtab |