Make sure we do not pass multiple CGI parameters in function calls
[ikiwiki.git] / IkiWiki / Plugin / goto.pm
1 #!/usr/bin/perl
2 package IkiWiki::Plugin::goto;
3
4 use warnings;
5 use strict;
6 use IkiWiki 3.00;
7
8 sub import {
9         hook(type => "cgi", id => 'goto',  call => \&cgi);
10         hook(type => "getsetup", id => 'goto',  call => \&getsetup);
11 }
12
13 sub getsetup () {
14         return
15                 plugin => {
16                         safe => 1,
17                         rebuild => 0,
18                         section => "web",
19                 }
20 }
21
22 # cgi_goto(CGI, [page])
23 # Redirect to a specified page, or display "not found". If not specified,
24 # the page param from the CGI object is used.
25 sub cgi_goto ($;$) {
26         my $q = shift;
27         my $page = shift;
28
29         if (!defined $page) {
30                 $page = IkiWiki::decode_utf8(scalar $q->param("page"));
31
32                 if (!defined $page) {
33                         error("missing page parameter");
34                 }
35         }
36
37         # It's possible that $page is not a valid page name;
38         # if so attempt to turn it into one.
39         if ($page !~ /$config{wiki_file_regexp}/) {
40                 $page=titlepage($page);
41         }
42
43         IkiWiki::loadindex();
44
45         my $link;
46         if (! IkiWiki::isinternal($page)) {
47                 $link = bestlink("", $page);
48         }
49         elsif (defined $pagestate{$page}{meta}{permalink}) {
50                 # Can only redirect to an internal page if it has a
51                 # permalink.
52                 IkiWiki::redirect($q, $pagestate{$page}{meta}{permalink});
53         }
54
55         if (! defined $link || ! length $link) {
56                 IkiWiki::cgi_custom_failure(
57                         $q,
58                         "404 Not Found",
59                         IkiWiki::cgitemplate($q, gettext("missing page"),
60                                 "<p>".
61                                 sprintf(gettext("The page %s does not exist."),
62                                         htmllink("", "", $page)).
63                                 "</p>")
64                 )
65         }
66         else {
67                 IkiWiki::redirect($q, urlto($link));
68         }
69
70         exit;
71 }
72
73 sub cgi ($) {
74         my $cgi=shift;
75         my $do = $cgi->param('do');
76
77         if (defined $do && ($do eq 'goto' || $do eq 'commenter' ||
78                                $do eq 'recentchanges_link')) {
79                 # goto is the preferred name for this; recentchanges_link and
80                 # commenter are for compatibility with any saved URLs
81                 cgi_goto($cgi);
82         }
83 }
84
85 1;