summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Mitchell <davem@iabyn.com>2014-12-19 22:52:55 +0000
committerDavid Mitchell <davem@iabyn.com>2014-12-19 22:52:55 +0000
commitdb58a81c116b9bdc669c1b1a8cb7fd33627a926b (patch)
tree9e9ff71d712f6c848b7f9d57522fe56407411db7
parenta1b2073ef1dbfca70742296d373883902e6188b7 (diff)
downloadperl-db58a81c116b9bdc669c1b1a8cb7fd33627a926b.tar.gz
fix integer overflow in S_regpiece().
RExC_naughty is incremented when nasty bits of regex are found. If at the end of compilation, its > 01, then PREGf_NAUGHTY is set on the pattern. However, some bits of S_regpiece on detecting naughiness, double or nearly double RExC_naughty, quickly resulting in overflow of the I32. I've fixed it by skipping the doubling when RExC_naughty is large, but I don't know whether the doubling is conceptually wrong in the first place. Found by -fsanitize=undefined.
-rw-r--r--regcomp.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/regcomp.c b/regcomp.c
index 0ea7a5fbb7..8e146ace03 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -10859,7 +10859,8 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
do_curly:
if ((flags&SIMPLE)) {
- RExC_naughty += 2 + RExC_naughty / 2;
+ if (RExC_naughty < I32_MAX / 2)
+ RExC_naughty += 2 + RExC_naughty / 2;
reginsert(pRExC_state, CURLY, ret, depth+1);
Set_Node_Offset(ret, parse_start+1); /* MJD */
Set_Node_Cur_Length(ret, parse_start);
@@ -10885,7 +10886,8 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth)
REGTAIL(pRExC_state, ret, reg_node(pRExC_state, NOTHING));
if (SIZE_ONLY)
RExC_whilem_seen++, RExC_extralen += 3;
- RExC_naughty += 4 + RExC_naughty; /* compound interest */
+ if (RExC_naughty < I32_MAX / 4)
+ RExC_naughty += 4 + RExC_naughty; /* compound interest */
}
ret->flags = 0;