サニタイジングと URL 自動リンクのジレンマ 4

じゃあ htmlspecialchars() と ereg_replace() の順番を逆にすればええやんけー。
と思ってやってみると。

逆にした。

// 投稿されたメッセージを取得して
$message = $_POST[ "message" ];
// 先に URL をリンクに変換
$message = ereg_replace( "(https?|ftp)(://[[:alnum:]\+\$\;\?\.%,!#~*/:@&=_-]+)","<a href=\"\\1\\2\" target=\"_blank\">\\1\\2</a>", $message );
// その後に HTML サニタイジング
$message = htmlspecialchars( $message );

これが

<a href="http://exsample.com/test.cgi?page=10&mode=post">test</a>

ereg_replace() でこうなって

<a href="<a href="http://exsample.com/test.cgi?page=10&mode=post" target="_blank">http://exsample.com/test.cgi?page=10&mode=post</a>">test</a>

htmlspecialchars() でこうなる

&lt;a href=&quot;&lt;a href=&quot;http://exsample.com/test.cgi?page=10&amp;mode=post&quot; target=&quot;_blank&quot;&gt;http://exsample.com/test.cgi?page=10&amp;mode=post&lt;/a&gt;&quot;&gt;test&lt;/a&gt;

わかりにくいよ!

これをブラウザで表示すると

<a href="<a href="http://exsample.com/test.cgi?page=10&mode=post" target="_blank">http://exsample.com/test.cgi?page=10&mode=post</a>">test</a>

リンクのための <a> まで変換されちゃったよ!

と言うわけで。単純に htmlspecialchars() と ereg_replace() を逆にしてもダメ。

説明がわかりにくすぎて誰の役にも立たない気がしてきた罠。
続くの?

カテゴリ

トラックバック(0)

このブログ記事を参照しているブログ一覧: サニタイジングと URL 自動リンクのジレンマ 4

このブログ記事に対するトラックバックURL: http://je-pu-pu.jp/blog/mt-tb.cgi/163

コメント(6)

「つまらん! お前の話はつまらん!」(KINCHOのCMより)
KINCHOのCMより

URL貼り付け失敗! リトライ!

ttp://www.kincho.co.jp/cm/html/2004/kin_man/index.html

ぴんどめ :

まさにタイトル通りのことにどうしたものか考えていました。そして、このようなプログラムに行き着きました。

$string = htmlspecialchars($string);
$string = ereg_replace(
 "(https?://([A-Za-z0-9\+\$;\?\.%,!#~\*/:\@\(\)=_-]|(&amp;))+)",
 "\\1",
 $\string
);

サニタイズした文字列に & が単体で含まれることはないのでそれを利用しました。

これでもう問題ないかは確認してないですし、もう少し改良したほうが良いと思う部分もあります。でも、けっこう意図した通りの処理をしてくれます。

JE :

> ぴんどめさん

コメントありがとうございまーす。

その方法だと
_ttp://&#121;&#97;&#104;&#111;&#111;.co.jp/ を
http://yahoo.co.jp/
に正しく変換できない事が判明してしまいました。

僕の作ったライブラリでも試してみました。
http://je-pu-pu.jp/bbs.php?id=je-pu-pu&res=246
正しく変換できない事が判明です。がびーん。

mixi.jp で試してみました。
ちゃんと変換できる事が判明です。しょっく。

というわけで今日は自動リンク処理の修正でもしようかと思います。

キーワードは「文字参照」
http://www.asahi-net.or.jp/~sd5a-ucd/rec-html401j/appendix/notes.html#h-B.2.2
http://d.hatena.ne.jp/keyword/%CA%B8%BB%FA%BB%B2%BE%C8
http://www.eris.ais.ne.jp/~hiro/html/

またきてね。

ぴんどめ :

JE さん、コメントありがとうございます!

> その方法だと
> _ttp://&#121;&#97;&#104;&#111;&#111;.co.jp/ を
> http://yahoo.co.jp/
> に正しく変換できない事が判明してしまいました。

なるほど、参照文字を置換してリンクとされたいのですね。
サニタイズされた a 要素の一部がリンクに含まれないようにすることしか考えていませんでした。

個人的には、何かしらの意図がなければわざわざ文字参照で書き込むことはしないと思いますので、
先日書き込ませていただいたプログラムで良い気がしています。
しかし、# って URL に使用できる文字でしたっけ…?
その辺の自信がなくなってきました。

ちゃんと変換してあげたほうが親切な気もしますし、
併せてもう一度見直したり考えたりしてみようと思います。

ありがとうございます!

JE :

> ぴんどめさん

どうもこんばんわー。

その後よく考えてみたら・・・
文字参照は HTML を記述する時の記法なので、
掲示板の投稿に文字参照が使われてた場合の事は別に考慮しなくてもいいような気になりました。

それより

1. 文字列のどの部分を URL とみなすかの問題
2. URL とみなした文字列をサニタイジングするかどうかの問題

が気になり始めてしまいました。あぁ奥が深い。

ちなみに。# は URL に使えますよー。
http://www.asahi-net.or.jp/~sd5a-ucd/rec-html401j/intro/intro.html#fragment-uri
http://www.studyinghttp.net/uri#Character

良い自動リンクを。でわでわ。

コメントする

このブログ記事について

このページは、が2005年2月 9日 23:59に書いたブログ記事です。

ひとつ前のブログ記事は「落書きにタイトルを付けるのは難しい。」です。

次のブログ記事は「Thief 2 やってまーす。」です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。

Powered by Movable Type 4.0