From: David Mitchell Date: Tue, 12 Jan 2010 00:14:41 +0000 (+0000) Subject: fix for [perl #65582] anon globs segfaulting X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=1809c940bf4737dd262fc0c026e063316c466a28;p=p5sagit%2Fp5-mst-13.2.git fix for [perl #65582] anon globs segfaulting The following code has had differing behaviours: my $io_ref = *STDOUT{IO}; my $glob = *$io_ref; defined($glob) "$glob" -------------- ------- 5.8.8 false "" with uninit warning 5.10.0 true (coredump) this commit true "" $glob is essentially an anonymous typeglob (no NAME, EGV or GvSTASH). It shouldn't register as undefined since it's clearly a valid GV with a valid IO slot; Stringifying to "" seems to be the right thing, and not warning seems right too, since its not undef. --- diff --git a/sv.c b/sv.c index 063dd19..4e80e18 100644 --- a/sv.c +++ b/sv.c @@ -2986,11 +2986,17 @@ Perl_sv_2pv_flags(pTHX_ register SV *const sv, STRLEN *const lp, const I32 flags gv_efullname3(buffer, gv, "*"); SvFLAGS(gv) |= wasfake; - assert(SvPOK(buffer)); - if (lp) { - *lp = SvCUR(buffer); + if (SvPOK(buffer)) { + if (lp) { + *lp = SvCUR(buffer); + } + return SvPVX(buffer); + } + else { + if (lp) + *lp = 0; + return (char *)""; } - return SvPVX(buffer); } if (lp) diff --git a/t/op/gv.t b/t/op/gv.t index 1b705ef..72787c4 100644 --- a/t/op/gv.t +++ b/t/op/gv.t @@ -12,7 +12,7 @@ BEGIN { use warnings; require './test.pl'; -plan( tests => 178 ); +plan( tests => 181 ); # type coersion on assignment $foo = 'foo'; @@ -560,6 +560,27 @@ foreach my $type (qw(integer number string)) { "with the correct error message"); } +# RT #60954 anonymous glob should be defined, and not coredump when +# stringified. The behaviours are: +# +# defined($glob) "$glob" +# 5.8.8 false "" with uninit warning +# 5.10.0 true (coredump) +# 5.12.0 true "" + +{ + my $io_ref = *STDOUT{IO}; + my $glob = *$io_ref; + ok(defined $glob, "RT #60954 anon glob should be defined"); + + my $warn = ''; + local $SIG{__WARN__} = sub { $warn = $_[0] }; + use warnings; + my $str = "$glob"; + is($warn, '', "RT #60954 anon glob stringification shouln't warn"); + is($str, '', "RT #60954 anon glob stringification should be empty"); +} + __END__ Perl Rules