},
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\//,
}
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}/;
$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"));
}
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;
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"));
}
# 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");
}
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];
}
}
# 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"));
}
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;
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")));
}
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);
}
%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"));