sub fib {
my $num=shift;
- return 0 if $num == 1;
- return 1 if $num == 2;
+ return 0 if $num == 0;
+ return 1 if $num == 1;
return fib($num - 1) + fib($num - 2);
}
sub preprocess {
my %params=@_;
- my $num=$last++;
+ my $num=++$last;
return fib($num);
}
Looks like it works ok, doesn't it? That creates a page that lists:
- 1, 1, 3, 5, 8
+ 1, 1, 2, 3, 5
But what happens if there are two pages that both use fib? Try it out.
If ikiwiki builds both pages in one pass, the sequence will continue
sub preprocess {
my %params=@_;
my $page=$params{destpage};
- my $num=$last{$page}++;
+ my $num=++$last{$page};
return fib($num);
}
spot:
if (exists $params{seed}) {
- $last{$page}=$params{seed}-1;
+ $last{$page}=$params{seed};
}
But this highlights another issue with the plugin. The `fib()` function is
but that's not the focus of this tutorial. Instead, let's concentrate on
making the plugin use the existing function safely. A good first step would
be a guard on how high it will go.
-
+
my %last;
sub preprocess {
if (exists $params{seed}) {
$last{$page}=$params{seed}-1;
}
- my $num=$last{$page}++;
+ my $num=++$last{$page};
if ($num > 25) {
error "can only calculate the first 25 numbers in the sequence";
}
so that the user can look at the built page and see what went wrong.
Are we done? Nope, there's still a security hole. Consider what `fib()`
-does for numbers less than 1. Or for any number that's not an integer. In
+does for numbers less than 0. Or for any number that's not an integer. In
either case, it will run forever. Here's one way to fix that:
- if (int($num) != $num || $num < 1) {
+ if (int($num) != $num || $num < 0) {
error "positive integers only, please";
}