In perl.git, the branch smoke-me/regex-POISON has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/50cf28533639771de7e84e52748a8d0e0dcb5864?hp=5d9bf96febda46ec93db09012ec30997a4fbf7f9>

- Log -----------------------------------------------------------------
commit 50cf28533639771de7e84e52748a8d0e0dcb5864
Author: Nicholas Clark <n...@ccl4.org>
Date:   Thu Sep 13 18:13:43 2012 +0200

    Fix buggy -DPERL_POISON code in S_rxres_free(), exposed by a recent test.
    
    The code had been buggily attempting to overwrite just-freed memory since
    PERL_POISON was added by commit 94010e71b67db040 in June 2005. However, no
    regression test exercised this code path until recently.
    
    Also fix the offset in the array of UVs used by PERL_OLD_COPY_ON_WRITE to
    store RX_SAVED_COPY(). It now uses p[2]. Previously it had used p[1],
    directly conflicting with the use of p[1] to store RX_NPARENS().
    
    The code is too intertwined to meaningfully do these as separate commits.
-----------------------------------------------------------------------

Summary of changes:
 pp_ctl.c |   22 ++++++++++++----------
 1 files changed, 12 insertions(+), 10 deletions(-)

diff --git a/pp_ctl.c b/pp_ctl.c
index 1fc855d..1ff531d 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -366,13 +366,13 @@ Perl_rxres_save(pTHX_ void **rsp, REGEXP *rx)
     /* what (if anything) to free on croak */
     *p++ = PTR2UV(RX_MATCH_COPIED(rx) ? RX_SUBBEG(rx) : NULL);
     RX_MATCH_COPIED_off(rx);
+    *p++ = RX_NPARENS(rx);
 
 #ifdef PERL_OLD_COPY_ON_WRITE
     *p++ = PTR2UV(RX_SAVED_COPY(rx));
     RX_SAVED_COPY(rx) = NULL;
 #endif
 
-    *p++ = RX_NPARENS(rx);
     *p++ = PTR2UV(RX_SUBBEG(rx));
     *p++ = (UV)RX_SUBLEN(rx);
     *p++ = (UV)RX_SUBOFFSET(rx);
@@ -395,6 +395,7 @@ S_rxres_restore(pTHX_ void **rsp, REGEXP *rx)
     RX_MATCH_COPY_FREE(rx);
     RX_MATCH_COPIED_set(rx, *p);
     *p++ = 0;
+    RX_NPARENS(rx) = *p++;
 
 #ifdef PERL_OLD_COPY_ON_WRITE
     if (RX_SAVED_COPY(rx))
@@ -403,7 +404,6 @@ S_rxres_restore(pTHX_ void **rsp, REGEXP *rx)
     *p++ = 0;
 #endif
 
-    RX_NPARENS(rx) = *p++;
     RX_SUBBEG(rx) = INT2PTR(char*,*p++);
     RX_SUBLEN(rx) = (I32)(*p++);
     RX_SUBOFFSET(rx) = (I32)*p++;
@@ -423,18 +423,20 @@ S_rxres_free(pTHX_ void **rsp)
     PERL_UNUSED_CONTEXT;
 
     if (p) {
-#ifdef PERL_POISON
        void *tmp = INT2PTR(char*,*p);
-       Safefree(tmp);
-       if (*p)
-           PoisonFree(*p, 1, sizeof(*p));
+#ifdef PERL_POISON
+#ifdef PERL_OLD_COPY_ON_WRITE
+       U32 i = 9 + p[1] * 2;
 #else
-       Safefree(INT2PTR(char*,*p));
+       U32 i = 8 + p[1] * 2;
+#endif
+
+        PoisonFree(p, i, sizeof(UV));
 #endif
+       Safefree(tmp);
+
 #ifdef PERL_OLD_COPY_ON_WRITE
-       if (p[1]) {
-           SvREFCNT_dec (INT2PTR(SV*,p[1]));
-       }
+        SvREFCNT_dec (INT2PTR(SV*,p[2]));
 #endif
        Safefree(p);
        *rsp = NULL;

--
Perl5 Master Repository

Reply via email to