dcb3b7
From fc0fe26a7d286480c1bb25f57e469ece575bb68d Mon Sep 17 00:00:00 2001
dcb3b7
From: David Mitchell <davem@iabyn.com>
dcb3b7
Date: Thu, 7 Jul 2016 17:03:29 +0100
dcb3b7
Subject: [PATCH] SEGV in "Subroutine redefined" warning
dcb3b7
MIME-Version: 1.0
dcb3b7
Content-Type: text/plain; charset=UTF-8
dcb3b7
Content-Transfer-Encoding: 8bit
dcb3b7
dcb3b7
RT #128257
dcb3b7
dcb3b7
The following SEGVed:
dcb3b7
dcb3b7
    sub P::f{}
dcb3b7
    undef *P::;
dcb3b7
    *P::f =sub{};
dcb3b7
dcb3b7
due to the code which generates the "Subroutine STASH::NAME redefined"
dcb3b7
warning assuming that the GV always has a stash. Make it so that if it
dcb3b7
hasn't, the message changes to  "Subroutine NAME redefined" rather than
dcb3b7
just crashing.
dcb3b7
dcb3b7
Signed-off-by: Petr Písař <ppisar@redhat.com>
dcb3b7
---
dcb3b7
 sv.c              | 18 +++++++++++-------
dcb3b7
 t/lib/warnings/sv |  8 ++++++++
dcb3b7
 2 files changed, 19 insertions(+), 7 deletions(-)
dcb3b7
dcb3b7
diff --git a/sv.c b/sv.c
dcb3b7
index 1b7a283..0cbe371 100644
dcb3b7
--- a/sv.c
dcb3b7
+++ b/sv.c
dcb3b7
@@ -4074,14 +4074,18 @@ Perl_gv_setref(pTHX_ SV *const dstr, SV *const sstr)
dcb3b7
 			    CvCONST((const CV *)sref)
dcb3b7
 				 ? cv_const_sv((const CV *)sref)
dcb3b7
 				 : NULL;
dcb3b7
+                        HV * const stash = GvSTASH((const GV *)dstr);
dcb3b7
 			report_redefined_cv(
dcb3b7
-			   sv_2mortal(Perl_newSVpvf(aTHX_
dcb3b7
-				"%"HEKf"::%"HEKf,
dcb3b7
-				HEKfARG(
dcb3b7
-				 HvNAME_HEK(GvSTASH((const GV *)dstr))
dcb3b7
-				),
dcb3b7
-				HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr)))
dcb3b7
-			   )),
dcb3b7
+			   sv_2mortal(
dcb3b7
+                             stash
dcb3b7
+                               ? Perl_newSVpvf(aTHX_
dcb3b7
+				    "%"HEKf"::%"HEKf,
dcb3b7
+				    HEKfARG(HvNAME_HEK(stash)),
dcb3b7
+				    HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr))))
dcb3b7
+                               : Perl_newSVpvf(aTHX_
dcb3b7
+				    "%"HEKf,
dcb3b7
+				    HEKfARG(GvENAME_HEK(MUTABLE_GV(dstr))))
dcb3b7
+			   ),
dcb3b7
 			   cv,
dcb3b7
 			   CvCONST((const CV *)sref) ? &new_const_sv : NULL
dcb3b7
 			);
dcb3b7
diff --git a/t/lib/warnings/sv b/t/lib/warnings/sv
dcb3b7
index 5ddd4fe..c8e0e62 100644
dcb3b7
--- a/t/lib/warnings/sv
dcb3b7
+++ b/t/lib/warnings/sv
dcb3b7
@@ -413,3 +413,11 @@ Argument "a_c" isn't numeric in preincrement (++) at - line 5.
dcb3b7
 Argument "(?^:abc)" isn't numeric in preincrement (++) at - line 6.
dcb3b7
 Argument "123x" isn't numeric in preincrement (++) at - line 7.
dcb3b7
 Argument "123e" isn't numeric in preincrement (++) at - line 8.
dcb3b7
+########
dcb3b7
+# RT #128257 This used to SEGV
dcb3b7
+use warnings;
dcb3b7
+sub Foo::f {}
dcb3b7
+undef *Foo::;
dcb3b7
+*Foo::f =sub {};
dcb3b7
+EXPECT
dcb3b7
+Subroutine f redefined at - line 5.
dcb3b7
-- 
dcb3b7
2.5.5
dcb3b7