MyTextSanitizerのhtmlSpecialChars考 (1)
XOOPSのテキストサニタイザMyTextSanitizerには、htmlSpecialCharsというメソッドが存在しています。
このメソッド自体は、基本的にHTMLを許さない入力に対するサニタイズを行う事が目的の筈ですが、この内容と動作について、かなり前から完全な納得がいっていなかったので少し整理してみたいと思います。
<?php
/*
* for displaying data in html textbox forms
*
* @param string $text
*
* @return string
*/
function &htmlSpecialChars($text) {
$ret = preg_replace(array("/&/i", "/ /i"), array('&', '&nbsp;'), htmlspecialchars($text, ENT_QUOTES));
return $ret;
}
?>
ソースを見ると、いったんhtmlspecialchars()で、
変換前 | 変換後 |
& | & |
< | < |
> | > |
' | ' |
" | " |
の変換をおこなった後に、preg_replace()にて、
変換前 | 変換後 |
& | & |
| &nbsp; |
の置き換えを行っています。
このpreg_replace()部分も変換用配列の順序に依存しているので、少し判りにくいですが、
--(htmlspecialchars)-> &nbsp;
--(preg_replaceルール1)->
--(preg_replaceルール2)-> &nbsp;
という変換が行われる事になります。
その結果として、
変換前 | 変換後 |
& | & |
< | < |
> | > |
' | ' |
" | " |
| &nbsp; |
α | α |
あ | あ |
というような変換がされる事となります。
どうしてこの様な変換方法がとられているのでしょうか?
HTMLエンティティー文字が入力された場合に、これをブラウザにエンティティ文字として表示させる事が目的なのでは??
なんて勝手に考えてもいるのですが・・考えれば考えるほど頭が混乱してきています。
特に、 についての変換ルールは意味がわかりません。
空白文字を に強制変換するのであれば、整形目的及び、
<a href=<{$url}> >Link</a>
の様に値(この場合は、<{$url}>というSmarty変数)がクォートされていないHTML出力に対して、onclick= 等の形でJavaScriptの埋め込みを抑止する目的に使えるのですけど。
いずれにせよ、エンティティ文字を使用できる目的でも、編集時には入力したままの表記を再現させるために入力フォーム内の表示と、記事HTML出力では変換ルールを変えるべきかもしれませんね。
でないと、たとえば記事中に、
&
をそのまま表示させる場合に、現状の変換ルールを考慮に入れて
&amp;
と入力して投稿したとしても、再度編集画面を開くと、フォームのテキストボックスに、
&
と表示され、これに気がつかないままに再投稿すると記事中には、
&
が表示されてしまう事になります。
で再度編集画面を開くと、テキストボックスにも
&
が表示されて、記事中には結果として生の&文字が出力される事になってしまいます。
これ、かなり前からxoopscube.jpのフォーラムにも投稿されていた様ですけど、なんの答えも出ていなかったのですね。
現在のXOOPSとの互換性を極力崩さない形で、なにか対応する方法が無いかを、考えてみる事にします。
コメント
コメントの投稿
ごめんなさい、現在コメントを付けることは出来ません
$text = preg_replace(array("/&([^;]*[& =])/", "/&([^;]*$)/"), array("&\\1","&\\1"), $text);
(実体参照のampersand以外を探してるつもり)
上記のような変換は無意味でしょうか。
(http://okuhiki.dip.jp/modules/newbb/viewtopic.php?topic_id=65&forum=3
の、下から二つめの怪変部分です。)
Comment by Okuhiki — 2006年5月15日(月曜日) @ 09時22分43秒
【PHPネタ】htmlspecialchars関数はサニタイズ関数?
EUCの補助漢字をPHPでどのように処理するかを調べていて、1年前に自分で書いた
Trackback by WEBプログラミング NOW! — 2007年12月25日(火曜日) @ 10時06分41秒