相対リンクで、意図しないページへのリンクになることがある

  • ページ: BugTrack2
  • 投稿者: 名無しさん
  • 優先順位: 低
  • 状態: 提案
  • カテゴリー: 本体バグ
  • 投稿日: 2007-06-23 (土) 15:17:34
  • バージョン:

メッセージ

0/1////5/6/7?」のように途中の階層に空文字が含まれるページがあるとします。

上の階層のページから「.////5/6?」のように指定しても、 空文字の部分を消去してしまうので「./5/6」と書いたのと同じ動作になってしまいます。

同じように、下の階層(ここでは「0/1////5/6/7」とする)から「../」とした場合も、 「0/1////5/6」ではなく「0/1/5/6」とされてしまいます。

途中の階層に空文字が含まれるページを許さないのなら、is_pagename() の修正、 許すのならlib/make_link.php の修正となるのでしょうが、
ひとまずcvs:lib/make_link.php (v 1.35) を修正すると仮定して、修正案を書きます。

// $Id: make_link.php,v 1.35 2006/09/30 02:10:50 henoheno Exp $
// Copyright (C)
//   2003-2005 PukiWiki Developers Team
(中略)
// Resolve relative / (Unix-like)absolute path of the page
function get_fullname($name, $refer)
{
	global $defaultpage;

	// 'Here'
	if ($name == '' || $name == './') return $refer;

	// Absolute path
	if ($name{0} == '/') {
		$name = substr($name, 1);
		return ($name == '') ? $defaultpage : $name;
	}

	// Relative path from 'Here'
	if (substr($name, 0, 2) == './') {
-		$arrn    = preg_split('#/#', $name, -1, PREG_SPLIT_NO_EMPTY);
-		$arrn[0] = $refer;
-		return join('/', $arrn);
+		return $refer . substr($name, 1);
	}

	// Relative path from dirname()
	if (substr($name, 0, 3) == '../') {
-		$arrn = preg_split('#/#', $name,  -1, PREG_SPLIT_NO_EMPTY);
-		$arrp = preg_split('#/#', $refer, -1, PREG_SPLIT_NO_EMPTY);
+		if (substr($name, -1) == '/')
+			$name = substr($name, 0, -1);
+		$arrn = explode('/', $name);
+		$arrp = explode('/', $refer);

		while (! empty($arrn) && $arrn[0] == '..') {
			array_shift($arrn);
			array_pop($arrp);
		}
		$name = ! empty($arrp) ? join('/', array_merge($arrp, $arrn)) :
			(! empty($arrn) ? $defaultpage . '/' . join('/', $arrn) : $defaultpage);
	}

	return $name;
}

上では、「./hoge/」のように、最後が「/」である時のチェックをはずしています。
「./」とだけ書いた時は上のほうで処理してくれるので問題ないですし、
「[[BugTrack2/]]」のように相対表記でない時は、このチェックをしていないのでいいのかなと。

「../」の場合は、上階層のページそのものを指している時に、余分に削られては困るので、最後が「/」かどうかだけをチェックしています。
今いるページを指す$refer は、最後が「/」では無いはずですけど、
何らかの理由でそのようなページが存在した時のために、チェックしたほうがいいような気もします(上では、はずしてしまってます)。
階層を上がった結果が「0/1///」のようになってしまう可能性がありますが、
make_link.php ではこの処理を呼び出した直後に、is_pagename() を実行していますし、
他の場所でもis_page() や、is_file() などを実行している*1ので、特に問題は無いと思います。



*1 自作プラグインは、調べてないです

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2012-11-21 (水) 07:07:49
Site admin: PukiWiki Development Team

PukiWiki 1.5.2+ © 2001-2019 PukiWiki Development Team. Powered by PHP 5.6.40-0+deb8u7. HTML convert time: 0.227 sec.

OSDN