perl 5.002gamma: mg.c
Perl 5 Porters [Sat, 3 Feb 1996 17:43:39 +0000 (12:43 -0500)]
>From salzench@dun.nielsen.comSat Feb  3 15:17:03 1996
>Date: Sat, 3 Feb 1996 12:43:39 -0500 (EST)
>From: Chip Salzenberg <salzench@dun.nielsen.com>
>Reply to: chip@atlantic.net
>To: Perl 5 Porters <perl5-porters@africa.nicoh.com>
>Subject: Beta3: Possible typo in sv_unmagic() [edited]

>From salzench@dun.nielsen.comTue Feb  6 09:45:25 1996
>Date: Mon, 5 Feb 1996 00:09:09 -0500 (EST)
>From: Chip Salzenberg <salzench@dun.nielsen.com>
>Reply to: chip@atlantic.net
>To: Perl 5 Porters <perl5-porters@africa.nicoh.com>
>Subject: Beta3: Fix for 2nd magic SEGV

>From lwall@sems.comWed Feb  7 09:10:55 1996
>Date: Tue, 06 Feb 96 14:52:41 -0800
>From: Larry Wall <lwall@sems.com>
>To: perl5-porters@africa.nicoh.com
>Subject: study still busted

>The study itself work fine, but if you modify the string, it still thinks
>it is studied.  In some ways this is worse than study not working at all,
>as it did (or rather didn't) before.  Here's the test case:

mg.c

diff --git a/mg.c b/mg.c
index 1e37f45..9d69be5 100644 (file)
--- a/mg.c
+++ b/mg.c
@@ -98,17 +98,23 @@ SV* sv;
 {
     MGS* mgs;
     MAGIC* mg;
+    MAGIC** mgp;
 
     ENTER;
     mgs = save_magic(sv);
 
-    for (mg = SvMAGIC(sv); mg; mg = mg->mg_moremagic) {
+    mgp = &SvMAGIC(sv);
+    while ((mg = *mgp) != 0) {
        MGVTBL* vtbl = mg->mg_virtual;
        if (!(mg->mg_flags & MGf_GSKIP) && vtbl && vtbl->svt_get) {
            (*vtbl->svt_get)(sv, mg);
-           if (mg->mg_flags & MGf_GSKIP)
+           /* Ignore this magic if it's been deleted */
+           if (*mgp == mg && (mg->mg_flags & MGf_GSKIP))
                mgs->mgs_flags = 0;
        }
+       /* Advance to next magic (complicated by possible deletion) */
+       if (*mgp == mg)
+           mgp = &mg->mg_moremagic;
     }
 
     LEAVE;
@@ -992,6 +998,7 @@ SV* sv;
 MAGIC* mg;
 {
     mg->mg_len = -1;
+    SvSCREAM_off(sv);
     return 0;
 }