- $filename=linkpage(IkiWiki::possibly_foolish_untaint(
- attachment_location($form->field('page')).
- IkiWiki::basename($filename)));
- if (IkiWiki::file_pruned($filename, $config{srcdir})) {
+sub attachment_holding_location {
+ my $page=attachment_location(shift);
+
+ my $dir=$config{wikistatedir}."/attachments/".
+ IkiWiki::possibly_foolish_untaint(linkpage($page));
+ $dir=~s/\/$//;
+ return $dir;
+}
+
+sub is_held_attachment {
+ my $attachment=shift;
+
+ my $f=attachment_holding_location($attachment);
+ if (-f $f) {
+ return $f
+ }
+ else {
+ return undef;
+ }
+}
+
+# Stores the attachment in a holding area, not yet in the wiki proper.
+sub attachment_store {
+ my $filename=shift;
+ my $form=shift;
+ my $q=shift;
+ my $session=shift;
+
+ # 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) {
+ # 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::basename($filename);
+ $filename=~s/.*\\+(.+)/$1/; # hello, windows
+ $filename=IkiWiki::possibly_foolish_untaint(linkpage($filename));
+ my $dest=attachment_holding_location(scalar $form->field('page'));
+
+ # Check that the user is allowed to edit the attachment.
+ my $final_filename=
+ linkpage(IkiWiki::possibly_foolish_untaint(
+ attachment_location(scalar $form->field('page')))).
+ $filename;
+ eval {
+ if (IkiWiki::file_pruned($final_filename)) {