From 1ccf3d77864c3a3bec62b1f24e34a456f495c987 Mon Sep 17 00:00:00 2001 From: Alan Burlison Date: Wed, 21 Feb 2001 01:33:45 +0000 Subject: [PATCH] Fixed reference count loop caused by sv_magic. sv_magic is called from gv_fetchpv to create single-character magic variables (e.g. $!), and it is passed a sv and the gv that contains the sv as the mg_obj value. When sv_magic stores the mg_obj pointer it increments the gv refcount, thus causing a sv-gv pair that can't be freed. There is already a check for sv == obj which is used to prevent such reference loops. This change extends the check to cover the case described above. p4raw-id: //depot/maint-5.6/pureperl@8868 --- sv.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/sv.c b/sv.c index c6041c3..d550f2a 100644 --- a/sv.c +++ b/sv.c @@ -3316,10 +3316,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; -- 1.8.3.1