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