In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/db58a81c116b9bdc669c1b1a8cb7fd33627a926b?hp=ab3ebe974fa603224393cc703dcf1d58a58db38a>

- Log -----------------------------------------------------------------
commit db58a81c116b9bdc669c1b1a8cb7fd33627a926b
Author: David Mitchell <[email protected]>
Date:   Fri Dec 19 22:52:55 2014 +0000

    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.

M       regcomp.c

commit a1b2073ef1dbfca70742296d373883902e6188b7
Author: David Mitchell <[email protected]>
Date:   Fri Dec 19 22:35:48 2014 +0000

    fix integer overflow in S_study_chunk().
    
    It was adding to delta even when delta was already SSize_t_MAX
    
    This triggered it: /.*(ab|abc)/.
    
    Found by -fsanitize=undefined.

M       regcomp.c

commit 55b6a5f665b57d91246b00d58d8bf9ba32c7cdc3
Author: David Mitchell <[email protected]>
Date:   Fri Dec 19 22:19:58 2014 +0000

    fix integer overflow in S_study_chunk().
    
    It was adding SSize_t_MAX to data->last_start_max when
    data->last_start_max was already SSize_t_MAX.
    
    This triggered it: /(x+y)+/.
    
    Found by -fsanitize=undefined.

M       regcomp.c

commit 646e87871404a31d5a6c6ac42ca921078d055354
Author: David Mitchell <[email protected]>
Date:   Fri Dec 19 21:41:11 2014 +0000

    fix integer overflow in S_scan_commit().
    
    offset_float_max could end up as SSize_t_MAX+1.
    
    This triggered it: /^x(ab|c.+)$/.
    
    Found by -fsanitize=undefined.

M       regcomp.c

commit 2e2c882dd53d6b966a0cd3b0ef111ff9e85f2c41
Author: David Mitchell <[email protected]>
Date:   Fri Dec 19 20:31:00 2014 +0000

    add asan_ignore - which errors to ignore
    
    "clang -fsanitize=undefined" produces lots of false positives.
    This file allows certain functions to be excluded from checking.
    Use it as:
    
        clang -fsanitize=undefined -fsanitize-blacklist=`pwd`/asan_ignore

M       MANIFEST
A       asan_ignore
-----------------------------------------------------------------------

Summary of changes:
 MANIFEST    |  1 +
 asan_ignore | 19 +++++++++++++++++++
 regcomp.c   | 20 +++++++++++++-------
 3 files changed, 33 insertions(+), 7 deletions(-)
 create mode 100644 asan_ignore

diff --git a/MANIFEST b/MANIFEST
index 844b7ae..b3f0f2d 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,4 +1,5 @@
 Artistic               The "Artistic License"
+asan_ignore            Errors to skip under clang's Addresss Sanitizer
 AUTHORS                        Contact info for contributors
 autodoc.pl             Creates pod/perlintern.pod and pod/perlapi.pod
 av.c                   Array value code
diff --git a/asan_ignore b/asan_ignore
new file mode 100644
index 0000000..5a8bc5c
--- /dev/null
+++ b/asan_ignore
@@ -0,0 +1,19 @@
+# This file intended to be used with clang as
+#
+#  clang -fsanitize=foo -fsanitize-blacklist=`pwd`/asan_ignore
+#
+# It lists those files / functions that clang's Address Sanitizer should
+# ignore.
+#
+# See http://clang.llvm.org/docs/SanitizerSpecialCaseList.html.
+
+
+# The pp functions used under 'use integer' shouldn't warn about
+# integer overflow etc.
+#
+# Unfortunately there doesn't seem to be any way to disable just specific
+# errors (i.e. the integer overflow ones). The manual implies that you can
+# suffix with =foo for a "tool-specific category", but neither =undefined
+# nor =signed-integer-overflow worked.
+
+fun:Perl_pp_i_*
diff --git a/regcomp.c b/regcomp.c
index e5d6a76..8e146ac 100644
--- a/regcomp.c
+++ b/regcomp.c
@@ -928,8 +928,8 @@ S_scan_commit(pTHX_ const RExC_state_t *pRExC_state, 
scan_data_t *data,
        else { /* *data->longest == data->longest_float */
            data->offset_float_min = l ? data->last_start_min : data->pos_min;
            data->offset_float_max = (l
-                                     ? data->last_start_max
-                                     : (data->pos_delta == SSize_t_MAX
+                          ? data->last_start_max
+                          : (data->pos_delta > SSize_t_MAX - data->pos_min
                                         ? SSize_t_MAX
                                         : data->pos_min + data->pos_delta));
            if (is_inf
@@ -4888,8 +4888,11 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode 
**scanp,
                        } else {
                            /* start offset must point into the last copy */
                            data->last_start_min += minnext * (mincount - 1);
-                           data->last_start_max += is_inf ? SSize_t_MAX
-                               : (maxcount - 1) * (minnext + data->pos_delta);
+                           data->last_start_max =
+                              is_inf
+                               ? SSize_t_MAX
+                              : data->last_start_max +
+                                 (maxcount - 1) * (minnext + data->pos_delta);
                        }
                    }
                    /* It is counted once already... */
@@ -5511,7 +5514,8 @@ PerlIO_printf(Perl_debug_log, "LHS=%"UVuf" RHS=%"UVuf"\n",
                     data->longest = &(data->longest_float);
             }
             min += min1;
-            delta += max1 - min1;
+            if (delta != SSize_t_MAX)
+                delta += max1 - min1;
             if (flags & SCF_DO_STCLASS_OR) {
                 ssc_or(pRExC_state, data->start_class, (regnode_charclass *) 
&accum);
                 if (min1) {
@@ -10855,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);
@@ -10881,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;
 

--
Perl5 Master Repository

Reply via email to