summaryrefslogtreecommitdiff
path: root/regcomp.c
diff options
context:
space:
mode:
authorHugo van der Sanden <hv@crypt.org>2021-01-31 22:51:15 +0000
committerKarl Williamson <khw@cpan.org>2021-02-09 08:42:52 -0800
commit459be019bda14de383329366de4cdec161526c3f (patch)
tree62eb255181004cc9a8ca38161cc79cf8aff9abe8 /regcomp.c
parent3c7beb8da4692313468432f7e66606e56360d79c (diff)
downloadperl-459be019bda14de383329366de4cdec161526c3f.tar.gz
gh18515: fix special handling of specific split() patterns
Commit 122af31004 acted on the wrong assumption that NEXTOPER() and regnext() were equivalent, and in fixing a valgrind complaint tried to simplify code for detecting specific patterns for split() that merited special-case handling by making them all use regnext(). As a result, the special case /\s+/ was no longer correctly detected, resulting in a degree of pessimisation. This commit fixes that, and avoids reading via the calculated 'next' pointer except for the ops we need (in which cases we know it'll point to another regop) - for the EXACT case (which we don't need), valgrind was correctly pointing out that it points to potentially uninitialized data.
Diffstat (limited to 'regcomp.c')
-rw-r--r--regcomp.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/regcomp.c b/regcomp.c
index 30608745c2..d279244bc2 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -8434,8 +8434,12 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
* flags appropriately - Yves */
regnode *first = RExC_rxi->program + 1;
U8 fop = OP(first);
- regnode *next = regnext(first);
- U8 nop = OP(next);
+ regnode *next = NEXTOPER(first);
+ /* It's safe to read through *next only if OP(first) is a regop of
+ * the right type (not EXACT, for example).
+ */
+ U8 nop = (fop == NOTHING || fop == MBOL || fop == SBOL || fop == PLUS)
+ ? OP(next) : 0;
if (PL_regkind[fop] == NOTHING && nop == END)
RExC_rx->extflags |= RXf_NULL;
@@ -8448,13 +8452,13 @@ Perl_re_op_compile(pTHX_ SV ** const patternp, int pat_count,
RExC_rx->extflags |= RXf_START_ONLY;
else if (fop == PLUS
&& PL_regkind[nop] == POSIXD && FLAGS(next) == _CC_SPACE
- && nop == END)
+ && OP(regnext(first)) == END)
RExC_rx->extflags |= RXf_WHITE;
else if ( RExC_rx->extflags & RXf_SPLIT
&& (PL_regkind[fop] == EXACT && ! isEXACTFish(fop))
&& STR_LEN(first) == 1
&& *(STRING(first)) == ' '
- && nop == END )
+ && OP(regnext(first)) == END )
RExC_rx->extflags |= (RXf_SKIPWHITE|RXf_WHITE);
}