From 962b1c130cbbb61855e14244b7ccc9d96f9f1847 Mon Sep 17 00:00:00 2001 From: Giuseppe Bilotta Date: Sun, 2 Jan 2011 18:23:45 +0100 Subject: inline: pass the Atom/RSS titles to the templates The default templates are also updated to make use of this information. The rel="alternate" attribute is also inserted, for completeness. (cherry picked from commit 618ade535e6a7967a510d9e210edaef3d37cc9bc) --- IkiWiki/Plugin/inline.pm | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) (limited to 'IkiWiki/Plugin') diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm index 7c5da7343..e5a5c112e 100644 --- a/IkiWiki/Plugin/inline.pm +++ b/IkiWiki/Plugin/inline.pm @@ -290,8 +290,17 @@ sub preprocess_inline (@) { } } - my $rssurl=abs2rel($feedbase."rss".$feednum, dirname(htmlpage($params{destpage}))) if $feeds && $rss; - my $atomurl=abs2rel($feedbase."atom".$feednum, dirname(htmlpage($params{destpage}))) if $feeds && $atom; + my ($rssurl, $atomurl, $rssdesc, $atomdesc); + if ($feeds) { + if ($rss) { + $rssurl=abs2rel($feedbase."rss".$feednum, dirname(htmlpage($params{destpage}))); + $rssdesc = "$desc (RSS)"; + } + if ($atom) { + $atomurl=abs2rel($feedbase."atom".$feednum, dirname(htmlpage($params{destpage}))); + $atomdesc = "$desc (Atom)"; + } + } my $ret=""; @@ -302,8 +311,16 @@ sub preprocess_inline (@) { my $formtemplate=template_depends("blogpost.tmpl", $params{page}, blind_cache => 1); $formtemplate->param(cgiurl => IkiWiki::cgiurl()); $formtemplate->param(rootpage => rootpage(%params)); - $formtemplate->param(rssurl => $rssurl) if $feeds && $rss; - $formtemplate->param(atomurl => $atomurl) if $feeds && $atom; + if ($feeds) { + if ($rss) { + $formtemplate->param(rssurl => $rssurl); + $formtemplate->param(rssdesc => $rssdesc); + } + if ($atom) { + $formtemplate->param(atomurl => $atomurl); + $formtemplate->param(atomdesc => $atomdesc); + } + } if (exists $params{postformtext}) { $formtemplate->param(postformtext => $params{postformtext}); @@ -321,8 +338,14 @@ sub preprocess_inline (@) { elsif ($feeds && !$params{preview} && ($emptyfeeds || @feedlist)) { # Add feed buttons. my $linktemplate=template_depends("feedlink.tmpl", $params{page}, blind_cache => 1); - $linktemplate->param(rssurl => $rssurl) if $rss; - $linktemplate->param(atomurl => $atomurl) if $atom; + if ($rss) { + $linktemplate->param(rssurl => $rssurl); + $linktemplate->param(rssdesc => $rssdesc); + } + if ($atom) { + $linktemplate->param(atomurl => $atomurl); + $linktemplate->param(atomdesc => $atomdesc); + } $ret.=$linktemplate->output; } @@ -419,7 +442,7 @@ sub preprocess_inline (@) { genfeed("rss", $config{url}."/".$rssp, $desc, $params{guid}, $params{destpage}, @feedlist)); $toping{$params{destpage}}=1 unless $config{rebuild}; - $feedlinks{$params{destpage}}.=qq{}; + $feedlinks{$params{destpage}}.=qq{}; } } if ($atom) { @@ -429,7 +452,7 @@ sub preprocess_inline (@) { writefile($atomp, $config{destdir}, genfeed("atom", $config{url}."/".$atomp, $desc, $params{guid}, $params{destpage}, @feedlist)); $toping{$params{destpage}}=1 unless $config{rebuild}; - $feedlinks{$params{destpage}}.=qq{}; + $feedlinks{$params{destpage}}.=qq{}; } } } -- cgit v1.2.3 From 56259466ee806a258694670c5715bf02c6e7c212 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Thu, 6 Jan 2011 14:42:23 -0400 Subject: reword feed descs --- IkiWiki/Plugin/inline.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'IkiWiki/Plugin') diff --git a/IkiWiki/Plugin/inline.pm b/IkiWiki/Plugin/inline.pm index e5a5c112e..d89e14197 100644 --- a/IkiWiki/Plugin/inline.pm +++ b/IkiWiki/Plugin/inline.pm @@ -294,11 +294,11 @@ sub preprocess_inline (@) { if ($feeds) { if ($rss) { $rssurl=abs2rel($feedbase."rss".$feednum, dirname(htmlpage($params{destpage}))); - $rssdesc = "$desc (RSS)"; + $rssdesc = gettext("%s (RSS feed)", $desc); } if ($atom) { $atomurl=abs2rel($feedbase."atom".$feednum, dirname(htmlpage($params{destpage}))); - $atomdesc = "$desc (Atom)"; + $atomdesc = gettext("%s (Atom feed)", $desc); } } -- cgit v1.2.3 From 5d3998555ffbeb1c20b84dd4cdc46c825c07bec8 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 22 Jan 2011 10:06:17 -0400 Subject: fix uninitilized value warning on bad page name --- IkiWiki/Plugin/editpage.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'IkiWiki/Plugin') diff --git a/IkiWiki/Plugin/editpage.pm b/IkiWiki/Plugin/editpage.pm index df29bcc98..8c78e853c 100644 --- a/IkiWiki/Plugin/editpage.pm +++ b/IkiWiki/Plugin/editpage.pm @@ -91,12 +91,12 @@ sub cgi_editpage ($$) { # This untaint is safe because we check file_pruned and # wiki_file_regexp. my ($page)=$form->field('page')=~/$config{wiki_file_regexp}/; - $page=possibly_foolish_untaint($page); - my $absolute=($page =~ s#^/+##); # absolute name used to force location if (! defined $page || ! length $page || file_pruned($page)) { error(gettext("bad page name")); } + $page=possibly_foolish_untaint($page); + my $absolute=($page =~ s#^/+##); # absolute name used to force location my $baseurl = urlto($page); -- cgit v1.2.3 From dcfeaaad5b6ac478251e37be777de40da4d0909c Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 22 Jan 2011 10:15:33 -0400 Subject: comments: Fix XSS security hole due to missing validation of page name. Values have to be checked against wiki_file_regexp, not just file_pruned. Audited the rest of the code base for similar problems, found none. --- IkiWiki/Plugin/comments.pm | 4 ++-- debian/changelog | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'IkiWiki/Plugin') diff --git a/IkiWiki/Plugin/comments.pm b/IkiWiki/Plugin/comments.pm index 1287590a7..d9183970d 100644 --- a/IkiWiki/Plugin/comments.pm +++ b/IkiWiki/Plugin/comments.pm @@ -364,8 +364,8 @@ sub editcomment ($$) { } # The untaint is OK (as in editpage) because we're about to pass - # it to file_pruned anyway - my $page = $form->field('page'); + # it to file_pruned and wiki_file_regexp anyway. + my $page = $form->field('page')=~/$config{wiki_file_regexp}/; $page = IkiWiki::possibly_foolish_untaint($page); if (! defined $page || ! length $page || IkiWiki::file_pruned($page)) { diff --git a/debian/changelog b/debian/changelog index 36e4a9576..0165a240b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -4,6 +4,7 @@ ikiwiki (3.20110106) UNRELEASED; urgency=low to feed links. (Giuseppe Bilotta) * inline: Use class rather than id for feedlinks and blogform. (Giuseppe Bilotta) + * comments: Fix XSS security hole due to missing validation of page name. -- Joey Hess Thu, 06 Jan 2011 14:41:34 -0400 -- cgit v1.2.3 From b5d7469830e3569adc0664b645f1321ba54b3655 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Sat, 22 Jan 2011 10:20:38 -0400 Subject: rename: Fix crash when renaming a page that is linked to by a page in an underlay. Skip fixing links in such pages. The user will get a list of pages that still link to the old page. --- IkiWiki/Plugin/rename.pm | 1 + debian/changelog | 3 +++ 2 files changed, 4 insertions(+) (limited to 'IkiWiki/Plugin') diff --git a/IkiWiki/Plugin/rename.pm b/IkiWiki/Plugin/rename.pm index 57747d3c9..e871b815d 100644 --- a/IkiWiki/Plugin/rename.pm +++ b/IkiWiki/Plugin/rename.pm @@ -567,6 +567,7 @@ sub fixlinks ($$$) { } if ($needfix) { my $file=$pagesources{$page}; + next unless -e $config{srcdir}."/".$file; my $oldcontent=readfile($config{srcdir}."/".$file); my $content=renamepage_hook($page, $rename->{src}, $rename->{dest}, $oldcontent); if ($oldcontent ne $content) { diff --git a/debian/changelog b/debian/changelog index 0165a240b..bed0bd6b4 100644 --- a/debian/changelog +++ b/debian/changelog @@ -5,6 +5,9 @@ ikiwiki (3.20110106) UNRELEASED; urgency=low * inline: Use class rather than id for feedlinks and blogform. (Giuseppe Bilotta) * comments: Fix XSS security hole due to missing validation of page name. + (Thanks, Dave B.) + * rename: Fix crash when renaming a page that is linked to by a page + in an underlay. -- Joey Hess Thu, 06 Jan 2011 14:41:34 -0400 -- cgit v1.2.3 From dca6679a5442581746daf89e78ee83712a017b98 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Thu, 6 Jan 2011 00:15:28 +0000 Subject: autoindex: use add_autofile This does cause a minor regression: index pages are now committed individually rather than being a single commit per rebuild. This also means the autoindex regression test needs to trigger the autofile generation pass. --- IkiWiki/Plugin/autoindex.pm | 37 +++++++++++++++++++++---------------- t/autoindex.t | 19 +++++++++++++++++-- 2 files changed, 38 insertions(+), 18 deletions(-) (limited to 'IkiWiki/Plugin') diff --git a/IkiWiki/Plugin/autoindex.pm b/IkiWiki/Plugin/autoindex.pm index 11595e217..ba2dcb907 100644 --- a/IkiWiki/Plugin/autoindex.pm +++ b/IkiWiki/Plugin/autoindex.pm @@ -22,12 +22,23 @@ sub getsetup () { sub genindex ($) { my $page=shift; my $file=newpagefile($page, $config{default_pageext}); - my $template=template("autoindex.tmpl"); - $template->param(page => $page); - writefile($file, $config{srcdir}, $template->output); - if ($config{rcs}) { - IkiWiki::rcs_add($file); - } + + add_autofile($file, "autoindex", sub { + my $message = sprintf(gettext("creating index page %s"), + $page); + debug($message); + + my $template = template("autoindex.tmpl"); + $template->param(page => $page); + writefile($file, $config{srcdir}, $template->output); + + if ($config{rcs}) { + IkiWiki::disable_commit_hook(); + IkiWiki::rcs_add($file); + IkiWiki::rcs_commit_staged(message => $message); + IkiWiki::enable_commit_hook(); + } + }); } sub refresh () { @@ -66,7 +77,10 @@ sub refresh () { chdir($origdir) || die "chdir $origdir: $!"; } - + + # FIXME: some of this is probably redundant with add_autofile now, and + # the rest should perhaps be added to the autofile machinery + my %deleted; if (ref $wikistate{autoindex}{deleted}) { %deleted=%{$wikistate{autoindex}{deleted}}; @@ -109,18 +123,9 @@ sub refresh () { } if (@needed) { - if ($config{rcs}) { - IkiWiki::disable_commit_hook(); - } foreach my $page (@needed) { genindex($page); } - if ($config{rcs}) { - IkiWiki::rcs_commit_staged( - message => gettext("automatic index generation"), - ); - IkiWiki::enable_commit_hook(); - } } } diff --git a/t/autoindex.t b/t/autoindex.t index b1425c22e..04d668fbc 100755 --- a/t/autoindex.t +++ b/t/autoindex.t @@ -3,7 +3,7 @@ package IkiWiki; use warnings; use strict; -use Test::More tests => 22; +use Test::More tests => 28; BEGIN { use_ok("IkiWiki"); } BEGIN { use_ok("IkiWiki::Render"); } @@ -61,6 +61,9 @@ writefile("attached/pie.jpg", "t/tmp", "I lied, this isn't a real JPEG"); # "gone" disappeared just before this refresh pass so it still has a mtime $pagemtime{gone} = $pagectime{gone} = 1000000; +my %pages; +my @del; + IkiWiki::Plugin::autoindex::refresh(); # these pages are still on record as having been deleted, because they have @@ -83,12 +86,24 @@ ok(! -f "t/tmp/has_internal.mdwn"); ok(! exists $wikistate{autoindex}{deleted}{reinstated}); ok(! -f "t/tmp/reinstated.mdwn"); -# needs creating +# needs creating (deferred; part of the autofile mechanism now) ok(! exists $wikistate{autoindex}{deleted}{tags}); +%pages = (); +@del = (); +is($autofiles{"tags.mdwn"}{plugin}, "autoindex"); +IkiWiki::gen_autofile("tags.mdwn", \%pages, \@del); +is_deeply(\%pages, {"t/tmp/tags" => 1}) || diag explain \%pages; +is_deeply(\@del, []) || diag explain \@del; ok(-s "t/tmp/tags.mdwn"); # needs creating because of an attachment ok(! exists $wikistate{autoindex}{deleted}{attached}); +%pages = (); +@del = (); +is($autofiles{"attached.mdwn"}{plugin}, "autoindex"); +IkiWiki::gen_autofile("attached.mdwn", \%pages, \@del); +is_deeply(\%pages, {"t/tmp/attached" => 1}) || diag explain \%pages; +is_deeply(\@del, []) || diag explain \@del; ok(-s "t/tmp/attached.mdwn"); 1; -- cgit v1.2.3 From 8ee9eabb1c5314f51641aaec4cb45d5c2d0fa7b8 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Sat, 22 Jan 2011 22:28:50 +0000 Subject: autoindex: stop tracking deletions, use generic autofile tracking instead - Migrate the set of deletions to the {autofile} set, since it has more or less the same effect. This affects the "deleted" case in the test. - If a page has just been deleted, add it as an autofile anyway: by the time gen_autofile is called, it'll be in the list of deleted files, so it'll just be added to {autofile}. This affects the "gone" case in the test. - Behaviour change: we don't forget that a page with no reason to be re-created was deleted. This affects the 'expunged' and 'reinstated' cases in the test. --- IkiWiki/Plugin/autoindex.pm | 49 ++++++++++++++-------------------------- t/autoindex.t | 54 ++++++++++++++++++++++++++++++--------------- 2 files changed, 53 insertions(+), 50 deletions(-) (limited to 'IkiWiki/Plugin') diff --git a/IkiWiki/Plugin/autoindex.pm b/IkiWiki/Plugin/autoindex.pm index ba2dcb907..5a58c820a 100644 --- a/IkiWiki/Plugin/autoindex.pm +++ b/IkiWiki/Plugin/autoindex.pm @@ -78,53 +78,38 @@ sub refresh () { chdir($origdir) || die "chdir $origdir: $!"; } - # FIXME: some of this is probably redundant with add_autofile now, and - # the rest should perhaps be added to the autofile machinery - + # Compatibility code. + # + # {deleted} contains pages that have been deleted at some point. + # This plugin used to delete from the hash sometimes, but no longer + # does; in [[todo/autoindex_should_use_add__95__autofile]] Joey + # thought the old behaviour was probably a bug. + # + # The effect of listing a page in {deleted} was to avoid re-creating + # it; we migrate these pages to {autofile} which has the same effect. + # However, {autofile} contains source filenames whereas {deleted} + # contains page names. my %deleted; if (ref $wikistate{autoindex}{deleted}) { %deleted=%{$wikistate{autoindex}{deleted}}; + delete $wikistate{autoindex}{deleted}; } elsif (ref $pagestate{index}{autoindex}{deleted}) { - # compatability code + # an even older version %deleted=%{$pagestate{index}{autoindex}{deleted}}; delete $pagestate{index}{autoindex}; } if (keys %deleted) { foreach my $dir (keys %deleted) { - # remove deleted page state if the deleted page is re-added, - # or if all its subpages are deleted - if ($deleted{$dir} && (exists $pages{$dir} || - ! grep /^$dir\/.*/, keys %pages)) { - delete $deleted{$dir}; - } + my $file=newpagefile($dir, $config{default_pageext}); + $wikistate{autoindex}{autofile}{$file} = 1; } - $wikistate{autoindex}{deleted}=\%deleted; } - my @needed; foreach my $dir (keys %dirs) { - if (! exists $pages{$dir} && ! $deleted{$dir} && - grep /^$dir\/.*/, keys %pages) { - if (exists $IkiWiki::pagemtime{$dir}) { - # This page must have just been deleted, so - # don't re-add it. And remember it was - # deleted. - if (! ref $wikistate{autoindex}{deleted}) { - $wikistate{autoindex}{deleted}={}; - } - ${$wikistate{autoindex}{deleted}}{$dir}=1; - } - else { - push @needed, $dir; - } - } - } - - if (@needed) { - foreach my $page (@needed) { - genindex($page); + if (! exists $pages{$dir} && grep /^$dir\/.*/, keys %pages) { + genindex($dir); } } } diff --git a/t/autoindex.t b/t/autoindex.t index 2c1331da2..665f0dc1c 100755 --- a/t/autoindex.t +++ b/t/autoindex.t @@ -3,7 +3,7 @@ package IkiWiki; use warnings; use strict; -use Test::More tests => 33; +use Test::More tests => 37; BEGIN { use_ok("IkiWiki"); } BEGIN { use_ok("IkiWiki::Render"); } @@ -33,7 +33,8 @@ is(checkconfig(), 1); %pagesources=%pagemtime=%oldlinks=%links=%depends=%typedlinks=%oldtypedlinks= %destsources=%renderedfiles=%pagecase=%pagestate=(); -# pages that (we claim) were deleted in an earlier pass +# Pages that (we claim) were deleted in an earlier pass. We're using deleted, +# not autofile, to test backwards compat. $wikistate{autoindex}{deleted}{deleted} = 1; $wikistate{autoindex}{deleted}{expunged} = 1; $wikistate{autoindex}{deleted}{reinstated} = 1; @@ -66,33 +67,50 @@ my @del; IkiWiki::Plugin::autoindex::refresh(); -# these pages are still on record as having been deleted, because they have +# this page is still on record as having been deleted, because it has # a reason to be re-created -is($wikistate{autoindex}{deleted}{deleted}, 1); -is($wikistate{autoindex}{deleted}{gone}, 1); -ok(! exists $autofiles{deleted}); -ok(! exists $autofiles{gone}); +is($wikistate{autoindex}{autofile}{"deleted.mdwn"}, 1); +is($autofiles{"deleted.mdwn"}{plugin}, "autoindex"); +%pages = (); +@del = (); +IkiWiki::gen_autofile("deleted.mdwn", \%pages, \@del); +is_deeply(\%pages, {}) || diag explain \%pages; +is_deeply(\@del, []) || diag explain \@del; ok(! -f "t/tmp/deleted.mdwn"); + +# this page is tried as an autofile, but because it'll be in @del, it's not +# actually created +ok(! exists $wikistate{autoindex}{autofile}{"gone.mdwn"}); +%pages = (); +@del = ("gone.mdwn"); +is($autofiles{"gone.mdwn"}{plugin}, "autoindex"); +IkiWiki::gen_autofile("gone.mdwn", \%pages, \@del); +is_deeply(\%pages, {}) || diag explain \%pages; +is_deeply(\@del, ["gone.mdwn"]) || diag explain \@del; ok(! -f "t/tmp/gone.mdwn"); -# this page does not exist and has no reason to be re-created, so we forget -# about it - it will be re-created if it gains sub-pages -ok(! exists $wikistate{autoindex}{deleted}{expunged}); -ok(! exists $autofiles{expunged}); +# this page does not exist and has no reason to be re-created, but we no longer +# have a special case for that - see +# [[todo/autoindex_should_use_add__95__autofile]] - so it won't be created +# even if it gains subpages later +is($wikistate{autoindex}{autofile}{"expunged.mdwn"}, 1); +ok(! exists $autofiles{"expunged.mdwn"}); ok(! -f "t/tmp/expunged.mdwn"); # a directory containing only an internal page shouldn't be indexed -ok(! exists $wikistate{autoindex}{deleted}{has_internal}); -ok(! exists $autofiles{has_internal}); +ok(! exists $wikistate{autoindex}{autofile}{"has_internal.mdwn"}); +ok(! exists $autofiles{"has_internal.mdwn"}); ok(! -f "t/tmp/has_internal.mdwn"); -# this page was re-created, so it drops off the radar -ok(! exists $wikistate{autoindex}{deleted}{reinstated}); -ok(! exists $autofiles{reinstated}); +# this page was re-created, but that no longer gets a special case +# (see [[todo/autoindex_should_use_add__95__autofile]]) so it's the same as +# deleted +is($wikistate{autoindex}{autofile}{"reinstated.mdwn"}, 1); +ok(! exists $autofiles{"reinstated.mdwn"}); ok(! -f "t/tmp/reinstated.mdwn"); # needs creating (deferred; part of the autofile mechanism now) -ok(! exists $wikistate{autoindex}{deleted}{tags}); +ok(! exists $wikistate{autoindex}{autofile}{"tags.mdwn"}); %pages = (); @del = (); is($autofiles{"tags.mdwn"}{plugin}, "autoindex"); @@ -102,7 +120,7 @@ is_deeply(\@del, []) || diag explain \@del; ok(-s "t/tmp/tags.mdwn"); # needs creating because of an attachment -ok(! exists $wikistate{autoindex}{deleted}{attached}); +ok(! exists $wikistate{autoindex}{autofile}{"attached.mdwn"}); %pages = (); @del = (); is($autofiles{"attached.mdwn"}{plugin}, "autoindex"); -- cgit v1.2.3