Merge branch 'file_pruned_revamp'

master
Joey Hess 2010-04-20 18:18:39 -04:00
commit 64946f9198
8 changed files with 55 additions and 65 deletions

View File

@ -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}/;

View File

@ -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"));
}

View File

@ -36,18 +36,22 @@ sub refresh () {
my (%pages, %dirs);
foreach my $dir ($config{srcdir}, @{$config{underlaydirs}}, $config{underlaydir}) {
require File::Spec;
$dir=File::Spec->canonpath($dir);
find({
no_chdir => 1,
wanted => sub {
$_=decode_utf8($_);
if (IkiWiki::file_pruned($_, $dir)) {
my $file=File::Spec->canonpath(decode_utf8($_));
return if $file eq $dir;
$file=~s/^\Q$dir\E\/?//;
return unless length $file;
if (IkiWiki::file_pruned($file)) {
$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;

View File

@ -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,20 +644,16 @@ sub comments_pending () {
find({
no_chdir => 1,
wanted => sub {
$_=decode_utf8($_);
if (IkiWiki::file_pruned($_, $dir)) {
$File::Find::prune=1;
}
elsif (! -l $_ && ! -d _) {
$File::Find::prune=0;
my ($f)=/$config{wiki_file_regexp}/; # untaint
if (defined $f && $f =~ /\Q._comment\E$/) {
my $ctime=(stat($f))[10];
$f=~s/^\Q$dir\E\/?//;
my $file=decode_utf8($_);
$file=~s/^\Q$dir\E\/?//;
return if ! length $file || IkiWiki::file_pruned($file)
|| -l $_ || -d _ || $file !~ /\Q._comment\E$/;
my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint
if (defined $f) {
my $ctime=(stat($_))[10];
push @ret, [$f, $ctime];
}
}
}
}, $dir);
return @ret;

View File

@ -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;

View File

@ -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")));
}

View File

@ -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);
}

View File

@ -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"));