In perl.git, the branch blead has been updated

<http://perl5.git.perl.org/perl.git/commitdiff/339441efdfcbaef5dbf131db2224abb35f5ae920?hp=fbfb8de6cc8b1de9f24da32679c4d961cd32d61c>

- Log -----------------------------------------------------------------
commit 339441efdfcbaef5dbf131db2224abb35f5ae920
Author: David Mitchell <da...@iabyn.com>
Date:   Fri Mar 7 17:45:27 2014 +0000

    make core safe against HvAUX() realloc
    
    Since the HvAUX structure is just tacked onto the end of the HvARRAY()
    struct, code like this can do bad things:
    
        aux = HvAUX();
        ... something that might split hv ...
        aux->foo = ...; /* SEGV! */
    
    So I've visually audited core for places where HbAUX() is saved and then
    re-used, and re-initialised the var if it looks like HvARRAY() could
    have changed in the meantime.
    
    I've been very conservative about what might be unsafe. For example,
    destructors or __WARN__ handlers could call perl code that modifies the
    hash.

M       gv.c
M       hv.c

commit 70bc21b7ad97027997a11a7f2426306cb48874e3
Author: David Mitchell <da...@iabyn.com>
Date:   Fri Mar 7 17:13:07 2014 +0000

    sv.h: add some more flag usage commentary
    
    Also, move SVphv_SHAREKEYS up to be closer to SVf_UTF8 - they are the same
    flag bit, but it wasn't clear, since there was a big gap between them

M       sv.h
-----------------------------------------------------------------------

Summary of changes:
 gv.c | 10 +++-------
 hv.c | 19 +++++++++++++------
 sv.h | 13 ++++++++-----
 3 files changed, 24 insertions(+), 18 deletions(-)

diff --git a/gv.c b/gv.c
index ec05284..e402f6b 100644
--- a/gv.c
+++ b/gv.c
@@ -2263,7 +2263,6 @@ Perl_gv_check(pTHX_ HV *stash)
 {
     dVAR;
     I32 i;
-    struct xpvhv_aux *aux;
 
     PERL_ARGS_ASSERT_GV_CHECK;
 
@@ -2271,12 +2270,11 @@ Perl_gv_check(pTHX_ HV *stash)
        return;
 
     assert(SvOOK(stash));
-    aux = HvAUX(stash);
 
     for (i = 0; i <= (I32) HvMAX(stash); i++) {
         const HE *entry;
         /* mark stash is being scanned, to avoid recursing */
-        aux->xhv_aux_flags |= HvAUXf_SCAN_STASH;
+        HvAUX(stash)->xhv_aux_flags |= HvAUXf_SCAN_STASH;
        for (entry = HvARRAY(stash)[i]; entry; entry = HeNEXT(entry)) {
             GV *gv;
             HV *hv;
@@ -2310,7 +2308,7 @@ Perl_gv_check(pTHX_ HV *stash)
                             HEKfARG(GvNAME_HEK(gv)));
            }
        }
-        aux->xhv_aux_flags &= ~HvAUXf_SCAN_STASH;
+        HvAUX(stash)->xhv_aux_flags &= ~HvAUXf_SCAN_STASH;
     }
 }
 
@@ -2493,7 +2491,6 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
   {
     int filled = 0;
     int i;
-    struct xpvhv_aux *aux;
     bool deref_seen = 0;
 
 
@@ -2527,9 +2524,8 @@ Perl_Gv_AMupdate(pTHX_ HV *stash, bool destructing)
     }
 
     assert(SvOOK(stash));
-    aux = HvAUX(stash);
     /* initially assume the worst */
-    aux->xhv_aux_flags &= ~HvAUXf_NO_DEREF;
+    HvAUX(stash)->xhv_aux_flags &= ~HvAUXf_NO_DEREF;
 
     for (i = 1; i < NofAMmeth; i++) {
        const char * const cooky = PL_AMG_names[i];
diff --git a/hv.c b/hv.c
index a4624f0..91d4c39 100644
--- a/hv.c
+++ b/hv.c
@@ -1687,6 +1687,7 @@ Perl_hfree_next_entry(pTHX_ HV *hv, STRLEN *indexp)
                 /* warning: at this point HvARRAY may have been
                  * re-allocated, HvMAX changed etc */
             }
+            iter = HvAUX(hv); /* may have been realloced */
             iter->xhv_riter = -1;      /* HvRITER(hv) = -1 */
             iter->xhv_eiter = NULL;    /* HvEITER(hv) = NULL */
 #ifdef PERL_HASH_RANDOMIZE_KEYS
@@ -1785,7 +1786,6 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
     }
     hfreeentries(hv);
     if (SvOOK(hv)) {
-      struct xpvhv_aux * const aux = HvAUX(hv);
       struct mro_meta *meta;
       const char *name;
 
@@ -1802,7 +1802,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
       /* If this call originated from sv_clear, then we must check for
        * effective names that need freeing, as well as the usual name. */
       name = HvNAME(hv);
-      if (flags & HV_NAME_SETALL ? !!aux->xhv_name_u.xhvnameu_name : !!name) {
+      if (flags & HV_NAME_SETALL ? !!HvAUX(hv)->xhv_name_u.xhvnameu_name : 
!!name) {
         if (name && PL_stashcache) {
             DEBUG_o(Perl_deb(aTHX_ "hv_undef_flags clearing PL_stashcache for 
name '%"
                              HEKf"'\n", HvNAME_HEK(hv)));
@@ -1810,7 +1810,7 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
         }
        hv_name_set(hv, NULL, 0, flags);
       }
-      if((meta = aux->xhv_mro_meta)) {
+      if((meta = HvAUX(hv)->xhv_mro_meta)) {
        if (meta->mro_linear_all) {
            SvREFCNT_dec_NN(meta->mro_linear_all);
            /* mro_linear_current is just acting as a shortcut pointer,
@@ -1824,9 +1824,9 @@ Perl_hv_undef_flags(pTHX_ HV *hv, U32 flags)
        SvREFCNT_dec(meta->isa);
        SvREFCNT_dec(meta->super);
        Safefree(meta);
-       aux->xhv_mro_meta = NULL;
+       HvAUX(hv)->xhv_mro_meta = NULL;
       }
-      if (!aux->xhv_name_u.xhvnameu_name && ! aux->xhv_backreferences)
+      if (!HvAUX(hv)->xhv_name_u.xhvnameu_name && ! 
HvAUX(hv)->xhv_backreferences)
        SvFLAGS(hv) &= ~SVf_OOK;
     }
     if (!SvOOK(hv)) {
@@ -2009,12 +2009,13 @@ Perl_hv_iterinit(pTHX_ HV *hv)
        Perl_croak(aTHX_ "Bad hash");
 
     if (SvOOK(hv)) {
-       struct xpvhv_aux * const iter = HvAUX(hv);
+       struct xpvhv_aux * iter = HvAUX(hv);
        HE * const entry = iter->xhv_eiter; /* HvEITER(hv) */
        if (entry && HvLAZYDEL(hv)) {   /* was deleted earlier? */
            HvLAZYDEL_off(hv);
            hv_free_ent(hv, entry);
        }
+       iter = HvAUX(hv); /* may have been reallocated */
        iter->xhv_riter = -1;   /* HvRITER(hv) = -1 */
        iter->xhv_eiter = NULL; /* HvEITER(hv) = NULL */
 #ifdef PERL_HASH_RANDOMIZE_KEYS
@@ -2146,6 +2147,7 @@ Perl_hv_name_set(pTHX_ HV *hv, const char *name, U32 len, 
U32 flags)
                /* The first elem may be null. */
                if(*name) unshare_hek_or_pvn(*name, 0, 0, 0);
                Safefree(name);
+                iter = HvAUX(hv); /* may been realloced */
                spot = &iter->xhv_name_u.xhvnameu_name;
                iter->xhv_name_count = 0;
              }
@@ -2167,6 +2169,7 @@ Perl_hv_name_set(pTHX_ HV *hv, const char *name, U32 len, 
U32 flags)
            }
            else if (flags & HV_NAME_SETALL) {
                unshare_hek_or_pvn(iter->xhv_name_u.xhvnameu_name, 0, 0, 0);
+                iter = HvAUX(hv); /* may been realloced */
                spot = &iter->xhv_name_u.xhvnameu_name;
            }
            else {
@@ -2311,6 +2314,7 @@ Perl_hv_ename_delete(pTHX_ HV *hv, const char *name, U32 
len, U32 flags)
                : (HEK_LEN(*victim) == (I32)len && memEQ(HEK_KEY(*victim), 
name, len))
            ) {
                unshare_hek_or_pvn(*victim, 0, 0, 0);
+                aux = HvAUX(hv); /* may been realloced */
                if (count < 0) ++aux->xhv_name_count;
                else --aux->xhv_name_count;
                if (
@@ -2463,6 +2467,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags)
             SvREFCNT_dec(HeVAL(entry));
             Safefree(HeKEY_hek(entry));
             del_HE(entry);
+            iter = HvAUX(hv); /* may been realloced */
             iter->xhv_eiter = NULL; /* HvEITER(hv) = NULL */
            HvLAZYDEL_off(hv);
             return NULL;
@@ -2509,6 +2514,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags)
                              pTHX__FORMAT
                              pTHX__VALUE);
         }
+        iter = HvAUX(hv); /* may been realloced */
         iter->xhv_last_rand = iter->xhv_rand;
     }
 #endif
@@ -2553,6 +2559,7 @@ Perl_hv_iternext_flags(pTHX_ HV *hv, I32 flags)
        hv_free_ent(hv, oldentry);
     }
 
+    iter = HvAUX(hv); /* may been realloced */
     iter->xhv_eiter = entry; /* HvEITER(hv) = entry */
     return entry;
 }
diff --git a/sv.h b/sv.h
index a54fd8f..396a36b 100644
--- a/sv.h
+++ b/sv.h
@@ -405,21 +405,24 @@ perform the upgrade if necessary.  See C<svtype>.
 
 #define SVf_AMAGIC     0x10000000  /* has magical overloaded methods */
 
+/* note that SVf_AMAGIC is now only set on stashes, so this bit is free
+ * for non-HV SVs */
+
 /* Ensure this value does not clash with the GV_ADD* flags in gv.h: */
 #define SVf_UTF8        0x20000000  /* SvPV is UTF-8 encoded
                                       This is also set on RVs whose overloaded
                                       stringification is UTF-8. This might
                                       only happen as a side effect of SvPV() */
-                                          
-
-/* Some private flags. */
+/* PVHV */
+#define SVphv_SHAREKEYS 0x20000000  /* PVHV keys live on shared string table */
 
 /* PVAV could probably use 0x2000000 without conflict. I assume that PVFM can
    be UTF-8 encoded, and PVCVs could well have UTF-8 prototypes. PVIOs haven't
    been restructured, so sometimes get used as string buffers.  */
 
-/* PVHV */
-#define SVphv_SHAREKEYS 0x20000000  /* PVHV keys live on shared string table */
+
+/* Some private flags. */
+
 
 /* PVNV, PVMG only, and only used in pads. Should be safe to test on any scalar
    SV, as the core is careful to avoid setting both.

--
Perl5 Master Repository

Reply via email to