Skip to content

Commit

Permalink
Fix Issue #17372 - Deal with NOTHING regops in trie code properly
Browse files Browse the repository at this point in the history
We weren't handling NOTHING regops that were not followed
by a trieable type in the trie code.
  • Loading branch information
demerphq committed Jan 9, 2020
1 parent 1b173b1 commit ca902fb
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 2 deletions.
25 changes: 24 additions & 1 deletion regcomp.c
Original file line number Diff line number Diff line change
Expand Up @@ -2797,7 +2797,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;
Expand Down Expand Up @@ -3019,6 +3024,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
Expand Down Expand Up @@ -3080,7 +3088,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 */
Expand Down Expand Up @@ -3244,6 +3258,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
Expand Down Expand Up @@ -3284,6 +3301,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);
Expand Down
3 changes: 2 additions & 1 deletion t/re/re_tests
Original file line number Diff line number Diff line change
Expand Up @@ -2017,6 +2017,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

0 comments on commit ca902fb

Please sign in to comment.