リビジョン | 1dd1bb561c173b4f56857a9b43c2a83f76ae0674 (tree) |
---|---|
日時 | 2021-11-28 20:18:18 |
作者 | umorigu <umorigu@gmai...> |
コミッター | umorigu |
BugTrack/2525 Page-URI customization mechanism
Introduce PukiWikiStandardPageURIHandler class
* URI virtual query: '?' + pagename_encode($Page)
* Convert QueryString by PageURIHandler
* Support make_link
* Invalid page name mechanism
@@ -524,20 +524,17 @@ function page_list($pages, $cmd = 'read', $withfilename = FALSE) | ||
524 | 524 | mb_regex_encoding(SOURCE_ENCODING); |
525 | 525 | $readings = get_readings($pages); |
526 | 526 | } |
527 | - | |
528 | 527 | $list = $matches = array(); |
529 | - | |
530 | - // Shrink URI for read | |
531 | - if ($cmd == 'read') { | |
532 | - $href = $script . '?'; | |
533 | - } else { | |
534 | - $href = $script . '?cmd=' . $cmd . '&page='; | |
535 | - } | |
536 | 528 | uasort($pages, 'strnatcmp'); |
537 | 529 | foreach($pages as $file=>$page) { |
538 | - $r_page = pagename_urlencode($page); | |
539 | 530 | $s_page = htmlsc($page, ENT_QUOTES); |
540 | - $str = ' <li><a href="' . $href . $r_page . '">' . | |
531 | + // Shrink URI for read | |
532 | + if ($cmd == 'read') { | |
533 | + $href = get_page_uri($page); | |
534 | + } else { | |
535 | + $href = $script . '?cmd=' . $cmd . '&page=' . rawurlencode($page); | |
536 | + } | |
537 | + $str = ' <li><a href="' . $href . '">' . | |
541 | 538 | $s_page . '</a> ' . get_pg_passage($page); |
542 | 539 | if ($withfilename) { |
543 | 540 | $s_file = htmlsc($file); |
@@ -647,6 +644,21 @@ EOD; | ||
647 | 644 | exit; |
648 | 645 | } |
649 | 646 | |
647 | +function die_invalid_pagename() { | |
648 | + $title = 'Error'; | |
649 | + $page = 'Error: Invlid page name'; | |
650 | + $body = <<<EOD | |
651 | +<h3>Error</h3> | |
652 | +<strong>Error message: Invalid page name</strong> | |
653 | +EOD; | |
654 | + | |
655 | + pkwk_common_headers(); | |
656 | + header('HTTP/1.0 400 Bad request'); | |
657 | + catbody($title, $page, $body); | |
658 | + exit; | |
659 | +} | |
660 | + | |
661 | + | |
650 | 662 | // Have the time (as microtime) |
651 | 663 | function getmicrotime() |
652 | 664 | { |
@@ -861,11 +873,8 @@ function get_base_uri($uri_type = PKWK_URI_RELATIVE) | ||
861 | 873 | */ |
862 | 874 | function get_page_uri($page, $uri_type = PKWK_URI_RELATIVE) |
863 | 875 | { |
864 | - global $defaultpage; | |
865 | - if ($page === $defaultpage) { | |
866 | - return get_base_uri($uri_type); | |
867 | - } | |
868 | - return get_base_uri($uri_type) . '?' . pagename_urlencode($page); | |
876 | + global $page_uri_handler; | |
877 | + return get_base_uri($uri_type) . $page_uri_handler->get_page_uri_virtual_query($page); | |
869 | 878 | } |
870 | 879 | |
871 | 880 | // Get absolute-URI of this script |
@@ -1180,6 +1189,34 @@ function get_preg_u() { | ||
1180 | 1189 | return $utf8u; |
1181 | 1190 | } |
1182 | 1191 | |
1192 | +// Default Page name - URI mapping handler | |
1193 | +class PukiWikiStandardPageURIHandler { | |
1194 | + function filter_raw_query_string($query_string) { | |
1195 | + return $query_string; | |
1196 | + } | |
1197 | + | |
1198 | + function get_page_uri_virtual_query($page) { | |
1199 | + return '?' . pagename_urlencode($page); | |
1200 | + } | |
1201 | + | |
1202 | + function get_page_from_query_string($query_string) { | |
1203 | + $param1st = preg_replace("#^([^&]*)&.*$#", "$1", $query_string); | |
1204 | + if ($param1st == '') { | |
1205 | + return null; // default page | |
1206 | + } | |
1207 | + if (strpos($param1st, '=') !== FALSE) { | |
1208 | + // Found '/?key=value' (NG chars) | |
1209 | + return FALSE; // Error page | |
1210 | + } | |
1211 | + $page = urldecode($param1st); | |
1212 | + $page2 = input_filter($page); | |
1213 | + if ($page !== $page2) { | |
1214 | + return FALSE; // Error page | |
1215 | + } | |
1216 | + return $page2; | |
1217 | + } | |
1218 | +} | |
1219 | + | |
1183 | 1220 | //// Compat //// |
1184 | 1221 | |
1185 | 1222 | // is_a -- Returns TRUE if the object is of this class or has this class as one of its parents |
@@ -63,6 +63,12 @@ if (! file_exists(INI_FILE) || ! is_readable(INI_FILE)) { | ||
63 | 63 | if ($die) die_message(nl2br("\n\n" . $die)); |
64 | 64 | |
65 | 65 | ///////////////////////////////////////////////// |
66 | +// Page-URI mapping handler (default) | |
67 | +if (! $page_uri_handler) { | |
68 | + $page_uri_handler = new PukiWikiStandardPageURIHandler(); | |
69 | +} | |
70 | + | |
71 | +///////////////////////////////////////////////// | |
66 | 72 | // INI_FILE: LANG に基づくエンコーディング設定 |
67 | 73 | |
68 | 74 | // MB_LANGUAGE: mb_language (for mbstring extension) |
@@ -295,6 +301,21 @@ if (PKWK_QUERY_STRING_MAX && strlen($arg) > PKWK_QUERY_STRING_MAX) { | ||
295 | 301 | } |
296 | 302 | $arg = input_filter($arg); // \0 除去 |
297 | 303 | |
304 | +// Convert QueryString by PageURIHandler | |
305 | +$arg_replaced = $page_uri_handler->filter_raw_query_string($arg); | |
306 | +if ($arg_replaced !== $arg) { | |
307 | + $_GET = array(); | |
308 | + $m = array(); | |
309 | + foreach (explode('&', $arg_replaced) as $kv) { | |
310 | + if (preg_match('/^([^=]+)(=(.+))?/', $kv, $m)) { | |
311 | + $_GET[$m[1]] = is_null($m[3]) ? '' : $m[3]; | |
312 | + } | |
313 | + } | |
314 | + unset($m); | |
315 | + $arg = $arg_replaced; | |
316 | +} | |
317 | +unset($arg_replaced); | |
318 | + | |
298 | 319 | // unset QUERY_STRINGs |
299 | 320 | foreach (array('QUERY_STRING', 'argv', 'argc') as $key) { |
300 | 321 | unset(${$key}, $_SERVER[$key], $HTTP_SERVER_VARS[$key]); |
@@ -398,13 +419,14 @@ if (isset($get['md5']) && $get['md5'] != '' && | ||
398 | 419 | if (! isset($vars['cmd']) && ! isset($vars['plugin'])) { |
399 | 420 | |
400 | 421 | $get['cmd'] = $post['cmd'] = $vars['cmd'] = 'read'; |
401 | - | |
402 | - $arg = preg_replace("#^([^&]*)&.*$#", "$1", $arg); | |
403 | - if ($arg == '') $arg = $defaultpage; | |
404 | - if (strpos($arg, '=') !== false) $arg = $defaultpage; // Found '/?key=value' | |
405 | - $arg = urldecode($arg); | |
406 | - $arg = strip_bracket($arg); | |
407 | - $arg = input_filter($arg); | |
422 | + $arg = $page_uri_handler->get_page_from_query_string($arg); | |
423 | + if ($arg === FALSE) { | |
424 | + // page is FALSE if page name is not valid | |
425 | + // Keep $arg is FALSE | |
426 | + } else if (!$arg) { | |
427 | + // if $arg is null or '' ($arg is NOT FALSE) | |
428 | + $arg = $defaultpage; | |
429 | + } | |
408 | 430 | $get['page'] = $post['page'] = $vars['page'] = $arg; |
409 | 431 | } |
410 | 432 |
@@ -854,9 +854,6 @@ function make_pagelink($page, $alias = '', $anchor = '', $refer = '', $isautolin | ||
854 | 854 | |
855 | 855 | if ($page == '') return '<a href="' . $anchor . '">' . $s_alias . '</a>'; |
856 | 856 | |
857 | - $r_page = pagename_urlencode($page); | |
858 | - $r_refer = ($refer == '') ? '' : '&refer=' . rawurlencode($refer); | |
859 | - | |
860 | 857 | $page_filetime = fast_get_filetime($page); |
861 | 858 | $is_page = $page_filetime !== 0; |
862 | 859 | if (! isset($related[$page]) && $page !== $vars['page'] && $is_page) { |
@@ -877,12 +874,14 @@ function make_pagelink($page, $alias = '', $anchor = '', $refer = '', $isautolin | ||
877 | 874 | if ($s_page !== $s_alias) { |
878 | 875 | $title_attr_html = ' title="' . $s_page . '"'; |
879 | 876 | } |
880 | - return $al_left . '<a ' . 'href="' . $script . '?' . $r_page . $anchor . | |
877 | + return $al_left . '<a ' . 'href="' . get_page_uri($page) . $anchor . | |
881 | 878 | '"' . $title_attr_html . ' class="' . |
882 | 879 | $attrs['class'] . '" data-mtime="' . $attrs['data_mtime'] . |
883 | 880 | '">' . $s_alias . '</a>' . $al_right; |
884 | 881 | } else { |
885 | 882 | // Support Page redirection |
883 | + $r_page = rawurlencode($page); | |
884 | + $r_refer = ($refer == '') ? '' : '&refer=' . rawurlencode($refer); | |
886 | 885 | $redirect_page = get_pagename_on_redirect($page); |
887 | 886 | if ($redirect_page !== false) { |
888 | 887 | return make_pagelink($redirect_page, $s_alias); |
@@ -45,6 +45,10 @@ if ($notify) { | ||
45 | 45 | |
46 | 46 | ///////////////////////////////////////////////// |
47 | 47 | // Main |
48 | +if ($vars['page'] === FALSE) { | |
49 | + die_invalid_pagename(); | |
50 | + exit; | |
51 | +} | |
48 | 52 | if (manage_page_redirect()) { |
49 | 53 | exit; |
50 | 54 | } |
@@ -543,6 +543,11 @@ $logging_updates = 0; | ||
543 | 543 | $logging_updates_log_dir = '/var/log/pukiwiki'; |
544 | 544 | |
545 | 545 | ///////////////////////////////////////////////// |
546 | +// Page-URI mapping handler ( See https://pukiwiki.osdn.jp/?PukiWiki/PageURI ) | |
547 | +$page_uri_handler = null; // default | |
548 | +// $page_uri_handler = new PukiWikiStandardPageURIHandler(); | |
549 | + | |
550 | +///////////////////////////////////////////////// | |
546 | 551 | // User-Agent settings |
547 | 552 | // |
548 | 553 | // If you want to ignore embedded browsers for rich-content-wikisite, |