summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYves Orton <demerphq@gmail.com>2020-01-09 15:36:41 +0100
committerSteve Hay <steve.m.hay@googlemail.com>2020-02-12 17:57:17 +0000
commit3df4e022c7c354ad55f2ee5e104feeb180a23196 (patch)
tree9f16716075a2e6f0dbfbb667d245d62a832c6629
parent818b850a7d83272f593d35f86a9263ec4e83dcb1 (diff)
downloadperl-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.c25
-rw-r--r--t/re/re_tests3
2 files changed, 26 insertions, 2 deletions
diff --git a/regcomp.c b/regcomp.c
index ad52e70c2c..1874b36991 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -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