From b1dade8d960ce7ccb549e5652d35a8e9dbccf5c6 Mon Sep 17 00:00:00 2001 From: Joey Hess Date: Fri, 19 Mar 2010 14:52:17 -0400 Subject: [PATCH] allow multiple setup file types, and support safe parsing Finally removed the last hardcoding of IkiWiki::Setup::Standard. Take the first "IkiWiki::Setup::*" in the setup file to define the setuptype, and remember that type to use in dumping later. (But it can be overridden using --set, etc.) Also, support setup file types that are not evaled. --- IkiWiki.pm | 7 +++++++ IkiWiki/Setup.pm | 40 ++++++++++++++++++++++++++++----------- IkiWiki/Setup/Standard.pm | 4 +++- 3 files changed, 39 insertions(+), 12 deletions(-) diff --git a/IkiWiki.pm b/IkiWiki.pm index 6e333504e..241fb45b7 100644 --- a/IkiWiki.pm +++ b/IkiWiki.pm @@ -467,6 +467,13 @@ sub getsetup () { safe => 0, rebuild => 0, }, + setuptype => { + type => "internal", + default => "IkiWiki::Setup::Standard", + description => "perl class to use to dump setup file", + safe => 0, + rebuild => 0, + }, allow_symlinks_before_srcdir => { type => "boolean", default => 0, diff --git a/IkiWiki/Setup.pm b/IkiWiki/Setup.pm index a3fd5ce66..3accf3591 100644 --- a/IkiWiki/Setup.pm +++ b/IkiWiki/Setup.pm @@ -1,6 +1,8 @@ #!/usr/bin/perl -# Ikiwiki setup files are perl files that 'use IkiWiki::Setup::foo', -# passing it some sort of configuration data. +# Ikiwiki setup files can be perl files that 'use IkiWiki::Setup::foo', +# passing it some sort of configuration data. Or, they can contain +# the module name at the top, without the 'use', and the whole file is +# then fed into that module. package IkiWiki::Setup; @@ -10,24 +12,39 @@ use IkiWiki; use open qw{:utf8 :std}; use File::Spec; -sub load ($) { +sub load ($;$) { my $setup=IkiWiki::possibly_foolish_untaint(shift); + my $safemode=shift; + $config{setupfile}=File::Spec->rel2abs($setup); #translators: The first parameter is a filename, and the second #translators: is a (probably not translated) error message. open (IN, $setup) || error(sprintf(gettext("cannot read %s: %s"), $setup, $!)); - my $code; + my $content; { local $/=undef; - $code= || error("$setup: $!"); + $content= || error("$setup: $!"); } - - ($code)=$code=~/(.*)/s; close IN; - eval $code; - error("$setup: ".$@) if $@; + if ($content=~/(use\s+)?(IkiWiki::Setup::\w+)/) { + $config{setuptype}=$2; + if ($1) { + error sprintf(gettext("cannot load %s in safe mode"), $setup) + if $safemode; + eval IkiWiki::possibly_foolish_untaint($content); + error("$setup: ".$@) if $@; + } + else { + eval qq{require $config{setuptype}}; + error $@ if $@; + $config{setuptype}->loaddump(IkiWiki::possibly_foolish_untaint($content)); + } + } + else { + error sprintf(gettext("failed to parse %s"), $setup); + } } sub merge ($) { @@ -133,8 +150,9 @@ sub getsetup () { sub dump ($) { my $file=IkiWiki::possibly_foolish_untaint(shift); - require IkiWiki::Setup::Standard; - my @dump=IkiWiki::Setup::Standard::gendump("Setup file for ikiwiki."); + eval qq{require $config{setuptype}}; + error $@ if $@; + my @dump=$config{setuptype}->gendump("Setup file for ikiwiki."); open (OUT, ">", $file) || die "$file: $!"; print OUT "$_\n" foreach @dump; diff --git a/IkiWiki/Setup/Standard.pm b/IkiWiki/Setup/Standard.pm index f7a322317..4022ff03c 100644 --- a/IkiWiki/Setup/Standard.pm +++ b/IkiWiki/Setup/Standard.pm @@ -82,8 +82,10 @@ sub dumpvalues ($@) { return @ret; } -sub gendump ($) { +sub gendump ($$) { + my $class=shift; my $description=shift; + my %setup=(%config); my @ret;