attachment: Support perl 5.8's buggy version of CGI.pm.
authorJoey Hess <joey@kodama.kitenet.net>
Tue, 8 Jul 2008 22:10:05 +0000 (18:10 -0400)
committerJoey Hess <joey@kodama.kitenet.net>
Tue, 8 Jul 2008 22:10:53 +0000 (18:10 -0400)
This is truely horribly disgusting. CGI::tmpFileName, in current perls, is
an undocumented function (which should be a clue..) that takes the original
filename of an uploaded attachment, and returns the name of the tempfile
that CGI has stored it in.

In old perls, though, CGI::tmpFileName does not take a filename. It takes
a key from the object's {'.tmpfiles'} hash. This key is something
crazy like '*Fh::fh00001group' -- apparently the stringification of a
filehandle object.

Just to add to the fun, tmpFileName doesn't take the key, it expects a
refernce to the key. Argh?!

But the fun doesn't stop there, because in perl 5.8, CGI.pm is also broken
in two other ways. The upload() method is supposed to return a filehandle
to the temp file. It doesn't. The param() method is supposed to return
a filehandle to the temp file, that stringifies to the original filename.
It returns just the original filename, no filehandle.

Combine all these bugs, and you end up with this disgusting commit. Since
I have no way to get the filehandle, I *need* to get the tempfile name.
If I had the filehandle, I could probably pass it into tmpFileName, and
it might strigify to the right key name. But I don't, so the only way to
determine the key is to grub through the .tmpfiles hash ourselves.

And finally, one the temp file name is discovered, a filehandle can finally
be obtained by (re)opening it.

I recommend that this commit be reverted when perl 5.8 is a mercifully
faded memory.

I'm really, really, really glad I'm actually being paid for working on
this right now!

IkiWiki/Plugin/attachment.pm
debian/changelog
doc/bugs/attachment:_failed_to_get_filehandle.mdwn

index 84bf643905f75dccf9122dc4a91bbfc201cc7079..ef6d79a9c52a1db7006d223730a1636c6ab71bf6 100644 (file)
@@ -89,9 +89,17 @@ sub formbuilder (@) { #{{{
                # This is an (apparently undocumented) way to get the name
                # of the temp file that CGI writes the upload to.
                my $tempfile=$q->tmpFileName($filename);
                # This is an (apparently undocumented) way to get the name
                # of the temp file that CGI writes the upload to.
                my $tempfile=$q->tmpFileName($filename);
-               
                if (! defined $tempfile || ! length $tempfile) {
                if (! defined $tempfile || ! length $tempfile) {
-                       error("failed to determine tempfile name");
+                       # perl 5.8 needs an alternative, awful method
+                       if ($q =~ /HASH/ && exists $q->{'.tmpfiles'}) {
+                               foreach my $key (keys(%{$q->{'.tmpfiles'}})) {
+                                       $tempfile=$q->tmpFileName(\$key);
+                                       last if defined $tempfile && length $tempfile;
+                               }
+                       }
+                       if (! defined $tempfile || ! length $tempfile) {
+                               error("CGI::tmpFileName failed to return the uploaded file name");
+                       }
                }
 
                $filename=IkiWiki::titlepage(
                }
 
                $filename=IkiWiki::titlepage(
@@ -145,7 +153,7 @@ sub formbuilder (@) { #{{{
                                        # even that doesn't always work,
                                        # fall back to opening the tempfile
                                        $fh=undef;
                                        # even that doesn't always work,
                                        # fall back to opening the tempfile
                                        $fh=undef;
-                                       open($fh, "<", $tempfile) || error("failed to open $tempfile: $!");
+                                       open($fh, "<", $tempfile) || error("failed to open \"$tempfile\": $!");
                                }
                        }
                        binmode($fh);
                                }
                        }
                        binmode($fh);
index b933065d9dedef8708d802af65b7ce7e6aca6d44..725b9c1bc4b37d6a2019c2427ed1659946fd29a3 100644 (file)
@@ -7,6 +7,7 @@ ikiwiki (2.53) UNRELEASED; urgency=low
   * Fix a bug with links to pages whose names contained colons.
   * attachment: Support old versions of CGI.pm that lack an upload method.
   * Include ikiwiki.setup in examples in the debian package.
   * Fix a bug with links to pages whose names contained colons.
   * attachment: Support old versions of CGI.pm that lack an upload method.
   * Include ikiwiki.setup in examples in the debian package.
+  * attachment: Support perl 5.8's buggy version of CGI.pm.
 
  -- Joey Hess <joeyh@debian.org>  Mon, 07 Jul 2008 01:52:48 -0400
 
 
  -- Joey Hess <joeyh@debian.org>  Mon, 07 Jul 2008 01:52:48 -0400
 
index 9053e1abf5b516d6bd245c4cb3eae72fde2bda37..09546dcb5edbf31afac2d47084309cf1d759945c 100644 (file)
@@ -96,3 +96,7 @@ Is it Ikiwiki bug or my attachment plugin is misconfigured? --[[PaweĊ‚|ptecza]]
 
 > I've reproduced the bug, and it does seem to be a bug with the perl in
 > debian stable/ubuntu hardy. Trying to figure it out --[[Joey]]
 
 > I've reproduced the bug, and it does seem to be a bug with the perl in
 > debian stable/ubuntu hardy. Trying to figure it out --[[Joey]]
+
+> This was amazingly disgusting, see commit message for the full horror of
+> the details. I think it's [[done]] -- at least it works on debian stable
+> now. --[[Joey]]