Integrate change #8868 from pureperl to mainline.
Jarkko Hietaniemi [Wed, 21 Feb 2001 14:15:25 +0000 (14:15 +0000)]
Fixed reference count loop caused by sv_magic.

p4raw-link: @8868 on //depot/maint-5.6/pureperl: 1ccf3d77864c3a3bec62b1f24e34a456f495c987

p4raw-id: //depot/perl@8872
p4raw-integrated: from //depot/maint-5.6/pureperl@8870 'merge in' sv.c
(@8842..)

sv.c

diff --git a/sv.c b/sv.c
index e9dda52..bd4e427 100644 (file)
--- a/sv.c
+++ b/sv.c
@@ -3946,10 +3946,20 @@ Perl_sv_magic(pTHX_ register SV *sv, SV *obj, int how, const char *name, I32 nam
     }
     Newz(702,mg, 1, MAGIC);
     mg->mg_moremagic = SvMAGIC(sv);
-
     SvMAGIC(sv) = mg;
-    if (!obj || obj == sv || how == '#' || how == 'r')
+
+    /* Some magic sontains a reference loop, where the sv and object refer to
+       each other.  To prevent a avoid a reference loop that would prevent such
+       objects being freed, we look for such loops and if we find one we avoid
+       incrementing the object refcount. */
+    if (!obj || obj == sv || how == '#' || how == 'r' ||
+       (SvTYPE(obj) == SVt_PVGV &&
+           (GvSV(obj) == sv || GvHV(obj) == (HV*)sv || GvAV(obj) == (AV*)sv ||
+           GvCV(obj) == (CV*)sv || GvIOp(obj) == (IO*)sv ||
+           GvFORM(obj) == (CV*)sv)))
+    {
        mg->mg_obj = obj;
+    }
     else {
        mg->mg_obj = SvREFCNT_inc(obj);
        mg->mg_flags |= MGf_REFCOUNTED;