X-Git-Url: https://sipb.mit.edu/gitweb.cgi/ikiwiki.git/blobdiff_plain/2494a23fdd911eb7e85f2ea66607b4e08d87e927..fc1bad2e7b6922205ad079043fe3057b3628a2a8:/IkiWiki/Render.pm diff --git a/IkiWiki/Render.pm b/IkiWiki/Render.pm index e86314107..0fe20c64f 100644 --- a/IkiWiki/Render.pm +++ b/IkiWiki/Render.pm @@ -285,24 +285,26 @@ sub find_src_files () { find({ no_chdir => 1, wanted => sub { - $_=decode_utf8($_); - if (file_pruned($_, $config{srcdir})) { + my $file=decode_utf8($_); + $file=~s/^\Q$config{srcdir}\E\/?//; + my $page = pagename($file); + if (! exists $pagesources{$page} && + file_pruned($file)) { $File::Find::prune=1; + return; } - elsif (! -l $_ && ! -d _) { - my ($f)=/$config{wiki_file_regexp}/; # untaint - if (! defined $f) { - warn(sprintf(gettext("skipping bad filename %s"), $_)."\n"); - } - else { - $f=~s/^\Q$config{srcdir}\E\/?//; - push @files, $f; - my $page = pagename($f); - if ($pages{$page}) { - debug(sprintf(gettext("%s has multiple possible source pages"), $page)); - } - $pages{$page}=1; + return if -l $_ || -d _ || ! length $file; + + my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint + if (! defined $f) { + warn(sprintf(gettext("skipping bad filename %s"), $file)."\n"); + } + else { + push @files, $f; + if ($pages{$page}) { + debug(sprintf(gettext("%s has multiple possible source pages"), $page)); } + $pages{$page}=1; } }, }, $config{srcdir}); @@ -310,27 +312,28 @@ sub find_src_files () { find({ no_chdir => 1, wanted => sub { - $_=decode_utf8($_); - if (file_pruned($_, $dir)) { + my $file=decode_utf8($_); + $file=~s/^\Q$dir\E\/?//; + my $page=pagename($file); + if (! exists $pagesources{$page} && + file_pruned($file)) { $File::Find::prune=1; + return; } - elsif (! -l $_ && ! -d _) { - my ($f)=/$config{wiki_file_regexp}/; # untaint - if (! defined $f) { - warn(sprintf(gettext("skipping bad filename %s"), $_)."\n"); - } - else { - $f=~s/^\Q$dir\E\/?//; - # avoid underlaydir - # override attacks; see - # security.mdwn - if (! -l "$config{srcdir}/$f" && - ! -e _) { - my $page=pagename($f); - if (! $pages{$page}) { - push @files, $f; - $pages{$page}=1; - } + return if -l $_ || -d _ || ! length $file; + + my ($f) = $file =~ /$config{wiki_file_regexp}/; # untaint + if (! defined $f) { + warn(sprintf(gettext("skipping bad filename %s"), $file)."\n"); + } + else { + # avoid underlaydir override + # attacks; see security.mdwn + if (! -l "$config{srcdir}/$f" && + ! -e _) { + if (! $pages{$page}) { + push @files, $f; + $pages{$page}=1; } } } @@ -494,7 +497,7 @@ sub calculate_changed_links ($$$) { my $target=bestlink($page, $l); if (! exists $oldlink_targets->{$page}{$l} || $target ne $oldlink_targets->{$page}{$l}) { - $backlinkchanged{$l}=1; + $backlinkchanged{$target}=1; $linkchangers{lc($page)}=1; } delete $oldlink_targets->{$page}{$l}; @@ -502,7 +505,7 @@ sub calculate_changed_links ($$$) { } if (exists $oldlink_targets->{$page} && %{$oldlink_targets->{$page}}) { - foreach my $target (keys %{$oldlink_targets->{$page}}) { + foreach my $target (values %{$oldlink_targets->{$page}}) { $backlinkchanged{$target}=1; } $linkchangers{lc($page)}=1; @@ -545,38 +548,53 @@ sub render_dependent ($$$$$$$) { } if (exists $depends{$p} && ! defined $reason) { - D: foreach my $d (keys %{$depends{$p}}) { - my $sub=pagespec_translate($d); + foreach my $dep (keys %{$depends{$p}}) { + my $sub=pagespec_translate($dep); next if $@ || ! defined $sub; # only consider internal files # if the page explicitly depends # on such files - my $internal_dep=$d =~ /internal\(/; - - my @candidates; - if ($depends{$p}{$d} & $IkiWiki::DEPEND_PRESENCE) { - @candidates=@exists_changed; - push @candidates, @$internal_new, @$internal_del - if $internal_dep; - } - if (($depends{$p}{$d} & ($IkiWiki::DEPEND_CONTENT | $IkiWiki::DEPEND_LINKS))) { - @candidates=@changed; - push @candidates, @$internal_new, @$internal_del, @$internal_changed - if $internal_dep; - } - - foreach my $file (@candidates) { - next if $file eq $f; - my $page=pagename($file); - if ($sub->($page, location => $p)) { - if ($depends{$p}{$d} & $IkiWiki::DEPEND_LINKS && - ! $depends{$p}{$d} & $IkiWiki::DEPEND_CONTENT) { - next unless $linkchangers->{lc($page)}; + my $internal_dep=$dep =~ /internal\(/; + + my $in=sub { + my $list=shift; + my $type=shift; + foreach my $file (@$list) { + next if $file eq $f; + my $page=pagename($file); + if ($sub->($page, location => $p)) { + if ($type == $IkiWiki::DEPEND_LINKS) { + next unless $linkchangers->{lc($page)}; + } + return $page; } - $reason = $page; - last D; } + return undef; + }; + + if ($depends{$p}{$dep} & $IkiWiki::DEPEND_CONTENT) { + last if $reason = + $in->(\@changed, $IkiWiki::DEPEND_CONTENT); + last if $internal_dep && ($reason = + $in->($internal_new, $IkiWiki::DEPEND_CONTENT) || + $in->($internal_del, $IkiWiki::DEPEND_CONTENT) || + $in->($internal_changed, $IkiWiki::DEPEND_CONTENT)); + } + if ($depends{$p}{$dep} & $IkiWiki::DEPEND_PRESENCE) { + last if $reason = + $in->(\@exists_changed, $IkiWiki::DEPEND_PRESENCE); + last if $internal_dep && ($reason = + $in->($internal_new, $IkiWiki::DEPEND_PRESENCE) || + $in->($internal_del, $IkiWiki::DEPEND_PRESENCE)); + } + if ($depends{$p}{$dep} & $IkiWiki::DEPEND_LINKS) { + last if $reason = + $in->(\@changed, $IkiWiki::DEPEND_LINKS); + last if $internal_dep && ($reason = + $in->($internal_new, $IkiWiki::DEPEND_LINKS) || + $in->($internal_del, $IkiWiki::DEPEND_LINKS) || + $in->($internal_changed, $IkiWiki::DEPEND_LINKS)); } } }