Perl_mg_clear() did not cope with the called magic deleting itself - fix this.
Nicholas Clark [Wed, 20 May 2009 22:02:07 +0000 (23:02 +0100)]
Should all routines that iterate over the magic chain be hardened against this?

mg.c

diff --git a/mg.c b/mg.c
index 1bc5bf7..75fee70 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -383,15 +383,18 @@ Perl_mg_clear(pTHX_ SV *sv)
 {
     const I32 mgs_ix = SSNEW(sizeof(MGS));
     MAGIC* mg;
+    MAGIC *nextmg;
 
     PERL_ARGS_ASSERT_MG_CLEAR;
 
     save_magic(mgs_ix, sv);
 
-    for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
+    for (mg = SvMAGIC(sv); mg; mg = nextmg) {
         const MGVTBL* const vtbl = mg->mg_virtual;
        /* omit GSKIP -- never set here */
 
+       nextmg = mg->mg_moremagic; /* it may delete itself */
+
        if (vtbl && vtbl->svt_clear)
            CALL_FPTR(vtbl->svt_clear)(aTHX_ sv, mg);
     }