This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
fix integer overflow in S_regpiece().
authorDavid Mitchell <davem@iabyn.com>
Fri, 19 Dec 2014 22:52:55 +0000 (22:52 +0000)
committerDavid Mitchell <davem@iabyn.com>
Fri, 19 Dec 2014 22:52:55 +0000 (22:52 +0000)
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.

regcomp.c

index 0ea7a5f..8e146ac 100644 (file)
--- 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;