diff options
-rw-r--r-- | IkiWiki.pm | 11 | ||||
-rw-r--r-- | IkiWiki/Plugin/attachment.pm | 2 | ||||
-rw-r--r-- | IkiWiki/Plugin/autoindex.pm | 10 | ||||
-rw-r--r-- | IkiWiki/Plugin/comments.pm | 16 | ||||
-rw-r--r-- | IkiWiki/Plugin/editpage.pm | 7 | ||||
-rw-r--r-- | IkiWiki/Plugin/rename.pm | 5 | ||||
-rw-r--r-- | IkiWiki/Receive.pm | 2 | ||||
-rwxr-xr-x | t/file_pruned.t | 55 |
8 files changed, 49 insertions, 59 deletions
diff --git a/IkiWiki.pm b/IkiWiki.pm index b37b1f344..6d3b6c606 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -355,7 +355,7 @@ sub getsetup () { }, wiki_file_prune_regexps => { type => "internal", - default => [qr/(^|\/)\.\.(\/|$)/, qr/^\./, qr/\/\./, + default => [qr/(^|\/)\.\.(\/|$)/, qr/^\//, qr/^\./, qr/\/\./, qr/\.x?html?$/, qr/\.ikiwiki-new$/, qr/(^|\/).svn\//, qr/.arch-ids\//, qr/{arch}\//, qr/(^|\/)_MTN\//, qr/(^|\/)_darcs\//, @@ -1843,15 +1843,8 @@ sub deptype (@) { } my $file_prune_regexp; -sub file_pruned ($;$) { +sub file_pruned ($) { my $file=shift; - if (@_) { - require File::Spec; - $file=File::Spec->canonpath($file); - my $base=File::Spec->canonpath(shift); - return if $file eq $base; - $file =~ s#^\Q$base\E/+##; - } if (defined $config{include} && length $config{include}) { return 0 if $file =~ m/$config{include}/; diff --git a/IkiWiki/Plugin/attachment.pm b/IkiWiki/Plugin/attachment.pm index ad1dd9bca..8c3ff887a 100644 --- a/IkiWiki/Plugin/attachment.pm +++ b/IkiWiki/Plugin/attachment.pm @@ -137,7 +137,7 @@ sub formbuilder (@) { $filename=linkpage(IkiWiki::possibly_foolish_untaint( attachment_location($form->field('page')). IkiWiki::basename($filename))); - if (IkiWiki::file_pruned($filename, $config{srcdir})) { + if (IkiWiki::file_pruned($filename)) { error(gettext("bad attachment filename")); } diff --git a/IkiWiki/Plugin/autoindex.pm b/IkiWiki/Plugin/autoindex.pm index c71d73349..23a17d4e9 100644 --- a/IkiWiki/Plugin/autoindex.pm +++ b/IkiWiki/Plugin/autoindex.pm @@ -39,15 +39,15 @@ sub refresh () { find({ no_chdir => 1, wanted => sub { - $_=decode_utf8($_); - if (IkiWiki::file_pruned($_, $dir)) { + my $file=decode_utf8($_); + $file=~s/^\Q$dir\E\/?//; + return unless length $file; + if (IkiWiki::file_pruned($_)) { $File::Find::prune=1; } elsif (! -l $_) { - my ($f)=/$config{wiki_file_regexp}/; # untaint + my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint return unless defined $f; - $f=~s/^\Q$dir\E\/?//; - return unless length $f; return if $f =~ /\._([^.]+)$/; # skip internal page if (! -d _) { $pages{pagename($f)}=1; diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm index 0aa043215..ccc9e1068 100644 --- a/IkiWiki/Plugin/comments.pm +++ b/IkiWiki/Plugin/comments.pm @@ -338,7 +338,7 @@ sub editcomment ($$) { my $page = $form->field('page'); $page = IkiWiki::possibly_foolish_untaint($page); if (! defined $page || ! length $page || - IkiWiki::file_pruned($page, $config{srcdir})) { + IkiWiki::file_pruned($page)) { error(gettext("bad page name")); } @@ -548,7 +548,7 @@ sub commentmoderation ($$) { # pending comment before untainting. my ($f)= $id =~ /$config{wiki_file_regexp}/; if (! defined $f || ! length $f || - IkiWiki::file_pruned($f, $config{srcdir})) { + IkiWiki::file_pruned($f)) { error("illegal file"); } @@ -644,16 +644,16 @@ sub comments_pending () { find({ no_chdir => 1, wanted => sub { - $_=decode_utf8($_); - if (IkiWiki::file_pruned($_, $dir)) { + my $file=decode_utf8($_); + $file=~s/^\Q$dir\E\/?//; + return unless length $file; + if (IkiWiki::file_pruned($_)) { $File::Find::prune=1; } elsif (! -l $_ && ! -d _) { - $File::Find::prune=0; - my ($f)=/$config{wiki_file_regexp}/; # untaint + my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint if (defined $f && $f =~ /\Q._comment\E$/) { - my $ctime=(stat($f))[10]; - $f=~s/^\Q$dir\E\/?//; + my $ctime=(stat($_))[10]; push @ret, [$f, $ctime]; } } diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm index 44fe5514a..26e38abc1 100644 --- a/IkiWiki/Plugin/editpage.pm +++ b/IkiWiki/Plugin/editpage.pm @@ -92,9 +92,9 @@ sub cgi_editpage ($$) { # wiki_file_regexp. my ($page)=$form->field('page')=~/$config{wiki_file_regexp}/; $page=possibly_foolish_untaint($page); - my $absolute=($page =~ s#^/+##); + my $absolute=($page =~ s#^/+##); # absolute name used to force location if (! defined $page || ! length $page || - file_pruned($page, $config{srcdir})) { + file_pruned($page)) { error(gettext("bad page name")); } @@ -220,8 +220,7 @@ sub cgi_editpage ($$) { my $best_loc; if (! defined $from || ! length $from || $from ne $form->field('from') || - file_pruned($from, $config{srcdir}) || - $from=~/^\// || + file_pruned($from) || $absolute || $form->submitted) { @page_locs=$best_loc=$page; diff --git a/IkiWiki/Plugin/rename.pm b/IkiWiki/Plugin/rename.pm index 1a9da6363..69e615ead 100644 --- a/IkiWiki/Plugin/rename.pm +++ b/IkiWiki/Plugin/rename.pm @@ -63,9 +63,8 @@ sub check_canrename ($$$$$$) { error(gettext("no change to the file name was specified")); } - # Must be a legal filename, and not absolute. - if (IkiWiki::file_pruned($destfile, $config{srcdir}) || - $destfile=~/^\//) { + # Must be a legal filename. + if (IkiWiki::file_pruned($destfile)) { error(sprintf(gettext("illegal name"))); } diff --git a/IkiWiki/Receive.pm b/IkiWiki/Receive.pm index cd94d0938..ae1bd8bef 100644 --- a/IkiWiki/Receive.pm +++ b/IkiWiki/Receive.pm @@ -82,7 +82,7 @@ sub test () { my ($file)=$change->{file}=~/$config{wiki_file_regexp}/; $file=IkiWiki::possibly_foolish_untaint($file); if (! defined $file || ! length $file || - IkiWiki::file_pruned($file, $config{srcdir})) { + IkiWiki::file_pruned($file)) { error(gettext("bad file name %s"), $file); } diff --git a/t/file_pruned.t b/t/file_pruned.t index f9c1c257e..34f366610 100755 --- a/t/file_pruned.t +++ b/t/file_pruned.t @@ -7,35 +7,34 @@ BEGIN { use_ok("IkiWiki"); } %config=IkiWiki::defaultconfig(); -ok(IkiWiki::file_pruned("src/.htaccess", "src")); -ok(IkiWiki::file_pruned("src/.ikiwiki/", "src")); -ok(IkiWiki::file_pruned("src/.ikiwiki/index", "src")); -ok(IkiWiki::file_pruned("src/CVS/foo", "src")); -ok(IkiWiki::file_pruned("src/subdir/CVS/foo", "src")); -ok(IkiWiki::file_pruned("src/.svn", "src")); -ok(IkiWiki::file_pruned("src/subdir/.svn", "src")); -ok(IkiWiki::file_pruned("src/subdir/.svn/foo", "src")); -ok(IkiWiki::file_pruned("src/.git", "src")); -ok(IkiWiki::file_pruned("src/subdir/.git", "src")); -ok(IkiWiki::file_pruned("src/subdir/.git/foo", "src")); -ok(! IkiWiki::file_pruned("src/svn/fo", "src")); -ok(! IkiWiki::file_pruned("src/git", "src")); -ok(! IkiWiki::file_pruned("src/index.mdwn", "src")); -ok(! IkiWiki::file_pruned("src/index.", "src")); +ok(IkiWiki::file_pruned(".htaccess")); +ok(IkiWiki::file_pruned(".ikiwiki/")); +ok(IkiWiki::file_pruned(".ikiwiki/index")); +ok(IkiWiki::file_pruned("CVS/foo")); +ok(IkiWiki::file_pruned("subdir/CVS/foo")); +ok(IkiWiki::file_pruned(".svn")); +ok(IkiWiki::file_pruned("subdir/.svn")); +ok(IkiWiki::file_pruned("subdir/.svn/foo")); +ok(IkiWiki::file_pruned(".git")); +ok(IkiWiki::file_pruned("subdir/.git")); +ok(IkiWiki::file_pruned("subdir/.git/foo")); +ok(! IkiWiki::file_pruned("svn/fo")); +ok(! IkiWiki::file_pruned("git")); +ok(! IkiWiki::file_pruned("index.mdwn")); +ok(! IkiWiki::file_pruned("index.")); +ok(IkiWiki::file_pruned(".")); +ok(IkiWiki::file_pruned("./")); -# these are ok because while the filename starts with ".", the canonpathed -# version does not -ok(! IkiWiki::file_pruned("src/.", "src")); -ok(! IkiWiki::file_pruned("src/./", "src")); +# absolute filenames are not allowed. +ok(IkiWiki::file_pruned("/etc/passwd")); +ok(IkiWiki::file_pruned("//etc/passwd")); +ok(IkiWiki::file_pruned("/")); +ok(IkiWiki::file_pruned("//")); +ok(IkiWiki::file_pruned("///")); -ok(IkiWiki::file_pruned("src/..", "src")); -ok(IkiWiki::file_pruned("src/../", "src")); -ok(IkiWiki::file_pruned("src/../", "src")); -ok(! IkiWiki::file_pruned("src", "src")); -ok(! IkiWiki::file_pruned("/.foo/src", "/.foo/src")); -ok(IkiWiki::file_pruned("/.foo/src/.foo/src", "/.foo/src")); -ok(! IkiWiki::file_pruned("/.foo/src/index.mdwn", "/.foo/src/index.mdwn")); +ok(IkiWiki::file_pruned("..")); +ok(IkiWiki::file_pruned("../")); -ok(IkiWiki::file_pruned("x/y/foo.dpkg-tmp", "src")); -ok(IkiWiki::file_pruned("x/y/foo.ikiwiki-new", "src")); +ok(IkiWiki::file_pruned("y/foo.dpkg-tmp")); +ok(IkiWiki::file_pruned("y/foo.ikiwiki-new")); |