From: Nicholas Clark Date: Mon, 22 Oct 2007 20:19:55 +0000 (+0000) Subject: SQL::Translator triggered a subtle piece of wrongness, whereby it X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=5e0caaeb4056614af54deb646e72147bdc6dcadc;p=p5sagit%2Fp5-mst-13.2.git SQL::Translator triggered a subtle piece of wrongness, whereby it managed to cause a proxy constant subroutine in the symbol table to be upgraded to a GV at precisely the point where it was being considered as a possible IO handle name. The core's user-space visible behaviour certainly was buggy - I believe this patch to be the correct fix. However, it seems to be very hard to write a test for it. p4raw-id: //depot/perl@32172 --- diff --git a/gv.c b/gv.c index 23c4e9f..9ab582d 100644 --- a/gv.c +++ b/gv.c @@ -875,6 +875,7 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, const I32 add = flags & ~GV_NOADD_MASK; const char *const name_end = nambeg + full_len; const char *const name_em1 = name_end - 1; + U32 faking_it; if (flags & GV_NOTQUAL) { /* Caller promised that there is no stash, so we can skip the check. */ @@ -1071,12 +1072,19 @@ Perl_gv_fetchpvn_flags(pTHX_ const char *nambeg, STRLEN full_len, I32 flags, return gv; } - /* Adding a new symbol */ + /* Adding a new symbol. + Unless of course there was already something non-GV here, in which case + we want to behave as if there was always a GV here, containing some sort + of subroutine. + Otherwise we run the risk of creating things like GvIO, which can cause + subtle bugs. eg the one that tripped up SQL::Translator */ + + faking_it = SvOK(gv); if (add & GV_ADDWARN && ckWARN_d(WARN_INTERNAL)) Perl_warner(aTHX_ packWARN(WARN_INTERNAL), "Had to create %s unexpectedly", nambeg); gv_init(gv, stash, name, len, add & GV_ADDMULTI); - gv_init_sv(gv, sv_type); + gv_init_sv(gv, faking_it ? SVt_PVCV : sv_type); if (isALPHA(name[0]) && ! (isLEXWARN_on ? ckWARN(WARN_ONCE) : (PL_dowarn & G_WARN_ON ) ) )