develooper Front page | perl.perl5.porters | Postings from October 2007

Re: BBC(Bleadperl Breaks CPAN) Today: SQL::Translator (0.08001)

Thread Previous | Thread Next
Nicholas Clark
October 22, 2007 15:17
Re: BBC(Bleadperl Breaks CPAN) Today: SQL::Translator (0.08001)
Message ID:
On Wed, Oct 03, 2007 at 06:30:45PM +0200, Andreas J. Koenig wrote:
> Maybe Nicholas will follow up with an explanation what is happening?

Um, this wasn't fun to track down. In fact, mid way I cleaned the bathroom in
preference. But I think I killed it dead dead dead.

Nicholas Clark

Change 32172 by nicholas@nicholas-saigo on 2007/10/22 20:19:55

	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.

Affected files ...

... //depot/perl/gv.c#385 edit

Differences ...

==== //depot/perl/gv.c#385 (text) ====

@@ -875,6 +875,7 @@
     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 @@
 	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 ) ) )

Thread Previous | Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About