X-Git-Url: http://git.vanrenterghem.biz/git.ikiwiki.info.git/blobdiff_plain/4e949e8a3108881ca78549437cdae124e14da72d..66f35e30dcea03c631a293e2341771277543b4ae:/IkiWiki/Plugin/attachment.pm diff --git a/IkiWiki/Plugin/attachment.pm b/IkiWiki/Plugin/attachment.pm index 3bbe27b1a..ed1cd61fe 100644 --- a/IkiWiki/Plugin/attachment.pm +++ b/IkiWiki/Plugin/attachment.pm @@ -20,7 +20,7 @@ sub formbuilder_setup (@) { #{{{ my $form=$params{form}; my $q=$params{cgi}; - if ($form->field("do") eq "edit") { + if (defined $form->field("do") && $form->field("do") eq "edit") { $form->field(name => 'attachment', type => 'file'); # These buttons are not put in the usual place, so # are not added to the normal formbuilder button list. @@ -34,7 +34,8 @@ sub formbuilder_setup (@) { #{{{ # Start with the attachments interface toggled invisible, # but if it was used, keep it open. if ($form->submitted ne "Upload Attachment" && - ! length $q->param("attachment_select")) { + (! defined $q->param("attachment_select") || + ! length $q->param("attachment_select"))) { $form->tmpl_param("attachments-class" => "toggleable"); } else { @@ -76,7 +77,7 @@ sub formbuilder (@) { #{{{ my $form=$params{form}; my $q=$params{cgi}; - return if $form->field("do") ne "edit"; + return if ! defined $form->field("do") || $form->field("do") ne "edit"; my $filename=$q->param('attachment'); if (defined $filename && length $filename && @@ -87,6 +88,10 @@ sub formbuilder (@) { #{{{ # of the temp file that CGI writes the upload to. my $tempfile=$q->tmpFileName($filename); + if (! defined $tempfile) { + error("failed to determine temp filename"); + } + $filename=IkiWiki::titlepage( IkiWiki::possibly_foolish_untaint( attachment_location($form->field('page')). @@ -132,7 +137,13 @@ sub formbuilder (@) { #{{{ else { my $fh=$q->upload('attachment'); if (! defined $fh || ! ref $fh) { - error("failed to get filehandle"); + # needed by old CGI versions + $fh=$q->param('attachment'); + if (! defined $fh || ! ref $fh) { + # even that doesn't always work, + # fall back to opening the tempfile + open($fh, "<", $tempfile) || error("failed to open $tempfile: $!"); + } } binmode($fh); writefile($filename, $config{srcdir}, undef, 1, sub { @@ -333,6 +344,44 @@ sub match_mimetype ($$;@) { #{{{ } } #}}} +sub match_virusfree ($$;@) { #{{{ + shift; + my $wanted=shift; + + my %params=@_; + if (! exists $params{file}) { + return IkiWiki::FailReason->new("no file specified"); + } + + if (! exists $IkiWiki::config{virus_checker} || + ! length $IkiWiki::config{virus_checker}) { + return IkiWiki::FailReason->new("no virus_checker configured"); + } + + # The file needs to be fed into the virus checker on stdin, + # because the file is not world-readable, and if clamdscan is + # used, clamd would fail to read it. + eval q{use IPC::Open2}; + error($@) if $@; + open (IN, "<", $params{file}) || return IkiWiki::FailReason->new("failed to read file"); + binmode(IN); + my $sigpipe=0; + $SIG{PIPE} = sub { $sigpipe=1 }; + my $pid=open2(\*CHECKER_OUT, "<&IN", $IkiWiki::config{virus_checker}); + my $reason=; + chomp $reason; + 1 while (); + close(CHECKER_OUT); + waitpid $pid, 0; + $SIG{PIPE}="DEFAULT"; + if ($sigpipe || $?) { + return IkiWiki::FailReason->new("file seems to contain a virus ($reason)"); + } + else { + return IkiWiki::SuccessReason->new("file seems virusfree ($reason)"); + } +} #}}} + sub match_ispage ($$;@) { #{{{ my $filename=shift;