htmlsc() 関連 †
- 元タイトル: lib/func.php [r1.104] の変更により、強調表示が無効化
- ページ: BugTrack2
- 投稿者: masao
- 優先順位: 低
- 状態: 完了
- カテゴリー: 本体バグ
- 投稿日: 2011-01-31 (月) 01:45:24
- バージョン:
強調表示が無効化 †
cvs:lib/func.php [r1.104] で導入された htmlsc() のデフォルトフラッグが ENT_QUOTES なので、cvs先端で「strong」のような強調構文が無効化されてようになっているようです。
diff -u -b -r1.104 func.php
--- lib/func.php 25 Jan 2011 15:01:01 -0000 1.104
+++ lib/func.php 30 Jan 2011 16:36:35 -0000
@@ -855,7 +855,7 @@
}
// Sugar with default settings
-function htmlsc($string = '', $flags = ENT_QUOTES, $charset = CONTENT_CHARSET)
+function htmlsc($string = '', $flags = ENT_COMPAT, $charset = CONTENT_CHARSET)
{
return htmlspecialchars($string, $flags, $charset); // htmlsc()
}
ひょっとすると $line_rules のほうを修正すべきかもしれませんが、、、とりあえず報告しておきます。
どうぞよろしくお願いします。
- 定義ルール(コンバート時に置換)で使うmake_line_rules関数へ渡す直前限定の話なら、デフォルトを変更よりhtmlsc関数をフラグ付きで呼び出せばいい話では?対象はcvs:lib/make_link.phpとcvs:plugin/ref.inc.phpの2つのはず(見落としてなければ) --
- 後方互換をあきらめる(昔の定義ルールを使わせない)なら、アナウンスした上で$line_rulesを(各自が追加したルールを含めて)変更してもらうですかね?(PHP関数:htmlspecialcharsの説明が正しければ、正規表現内の「'」を「'」に変更) --
- branch_r1_4_7と1.4.8以降で対応を分けるのか?も問題ですが --
- こんにちは。お知らせいただきありがとうございます。この辺りはセキュリティの土台として考えると譲れないので、短期的には格好悪いかもしれませんが $line_rules の方を直さざるをえなかろうと思っています(どちらのブランチも)。この関数の役目は、今後のつまらない問題を最初から払拭できるような、フィルタという名の土台です。 -- henoheno
- 仮に出力側を妥協させるならこのような穴を作った上、後段で 確実に ENT_QUOTES 相当の残りの処理をすれば つじつまが合うのですが、それはきっと(今の実装や設計が)ひどい事になるでしょう。安心できないという意味で危険も残ります。 -- henoheno
diff -u -r1.38 make_link.php
--- make_link.php 25 Jan 2011 15:01:01 -0000 1.38
+++ make_link.php 31 Jan 2011 14:12:28 -0000
@@ -97,7 +97,7 @@
$string = preg_replace_callback('/' . $this->pattern . '/x',
array(& $this, 'replace'), $string);
- $arr = explode("\x08", make_line_rules(htmlsc($string)));
+ $arr = explode("\x08", make_line_rules(htmlsc($string, ENT_COMPAT)));
$retval = '';
while (! empty($arr)) {
$retval .= array_shift($arr) . array_shift($this->result);
- 現実的かつ妥当な落としどころについて、ちょっと数日考えます。全体としてはHEADで落ち着いたらbranchにバックポートするという方向で。うーむうーむ -- henoheno
- $line_rules の側に単純に手を入れる場合、stupidな例ではこうなります -- henoheno
diff -u -r1.25 default.ini.php
--- default.ini.php 20 Dec 2005 14:04:40 -0000 1.25
+++ default.ini.php 31 Jan 2011 14:42:54 -0000
@@ -115,8 +115,8 @@
'SIZE\(([^\(\)]*)\):((?:(?!SIZE\([^\)]+\)\:).)*)' => '<span class="size$1">$2</span>',
'%%%(?!%)((?:(?!%%%).)*)%%%' => '<ins>$1</ins>',
'%%(?!%)((?:(?!%%).)*)%%' => '<del>$1</del>',
- "'''(?!')((?:(?!''').)*)'''" => '<em>$1</em>',
- "''(?!')((?:(?!'').)*)''" => '<strong>$1</strong>',
+ "'''(?!')((?:(?!''').)*)'''" => '<em>$1</em>',
+ "''(?!')((?:(?!'').)*)''" => '<strong>$1</strong>',
);
- 他に $line_rules の仕様に手を入れるとしたら: 置換に目をつぶるとしても、若干不満はあります。それは正規表現の左右端が '/' 決め打ちであり、左右端がそうなのかどうかが解り辛いので preg_quote() を使おうと思ったときに不安になり、かつ毎回動的な文字列連結によって正規表現が構築されている、といった部分です。*1 -- henoheno
- refに目を向けるため、まずは堅実かつstupidに行きます。 -- henoheno
- 今の実装だと、htmlspecialchars() が摘要された後に文字列置換を行っていますから、「エスケープ後の文字列」を考慮した正規表現を書かねばならないという宿命について大きな変化が無いようです。
とはいえこの見た目がひどいですが・・・ -- henoheno
- ですので、ENT_QUOTES を考慮する場合、これが本来期待される仕様だという事になります -- henoheno
- シングルクォートが文字列の中からなくなったので、BugTrack/779#x1fa3997してもよかったのでは?それと、refはChangeLogに挙がっていますが、ほかのhtmlsc()関連はクレジットの変更をしなくてよかったんでしょうか? --
- Cleanup扱いでクレジットの変更が必要がないのならスミマセン --
- 創造性が認められないような微修正にクレジットを主張するつもりは無いのですが、htmlsc() 関連は手を入れているとみなしており、そのCredit変更は、後でまとめてやろうと思っています。refは捕まってしまったので、先にやりました。refへのクリンナップは、今(手元で)大量にやっています。いつかは、やらねばならなかったのだ・・・ -- henoheno
- 途中で何回かコミットするかもしれません。ソースが読みやすくなっていると思いますが、ちょっとした互換性を失ってしまっている事があるかもしれません。自主的なチェックは最後に行います。何かお気づきの事があればぜひこちらにツッコミ入れて下さい。 -- henoheno
- cvs:plugin/ref.inc.php (r1.54)
- cvs:plugin/ref.inc.php (r1.55)
- r1.55のrefプラグインを試してみましたが、タイトルのオプションが効かなくなっているようです。ref_check_args()の実行結果をチェックせずに、$params['_title']を必ず上書きしているのが原因かと。 --
- BugTrack2/349#k68e563b PHP 5.4でのhtmlspecialchars()の非互換情報 --
refプラグイン †
- refにもありますか? 同じ問題かどうか、もしくは再現方法をお教えいただけると幸いです。続きの作業よりも優先して対応します。 -- henoheno
- refプラグインの説明でタイトルにあたる部分が指定されたときに
// 拡張パラメータをチェック
if (! empty($params['_args'])) {
$_title = array();
foreach ($params['_args'] as $arg) {
if (preg_match('/^([0-9]+)x([0-9]+)$/', $arg, $matches)) {
$params['_size'] = TRUE;
$params['_w'] = $matches[1];
$params['_h'] = $matches[2];
} else if (preg_match('/^([0-9.]+)%$/', $arg, $matches) && $matches[1] > 0) {
$params['_%'] = $matches[1];
} else {
$_title[] = $arg;
}
}
if (! empty($_title)) {
$title = htmlsc(join(',', $_title));
if ($is_image) $title = make_line_rules($title);
}
}
で使われています。 -- 2011-01-31 (月) 20:00:26コメント主
- 提示いただき、ありがとうございます。話題がはっきりしました。make_line_rules() を使っているのは、標準のプラグインではrefだけのようですね -- henoheno
- make_line_rues() や htmlspecialchars() をかける位置がよろしくない。目的や使い方とのズレが生じている。ようだ。zzz -- henoheno
別件: ref †
ただ今になってもう1つ気がついたのですが、cvs:plugin/ref.inc.php(r1.23)のときの
$title = join(',', $_title);
$title = $is_image ? htmlspecialchars($title) : make_line_rules(htmlspecialchars($title));
とは逆の条件で今はmake_line_rulesを実行しているので、
#ref(http://pukiwiki.sourceforge.jp/dev/image/top.png,''test'')
画像のときに
<img src="http://pukiwiki.sourceforge.jp/dev/image/top.png" alt="<strong>test</strong>" title="<strong>test</strong>" />
とaltの中などに<strong>が出力されて、noimg指定するか画像以外のときに
#ref(http://pukiwiki.sourceforge.jp/dev/image/top.png,noimg,''test'')
#ref(): File not found: "top.png" at page "http://pukiwiki.sourceforge.jp/dev/image"
となにも変化がない状態になるんですが -- 2011-01-31 (月) 20:00:26コメント主
RecentChanges のwikiソース生成部分の問題 †
今まではENT_QUOTES フラグでなかったので表面化しなかっただけみたいですが、'test'?のようにシングルクオートがページ名に含まれているとhtmlsc() でエスケープされて
[['test']]
とRecentChanges のwikiソースに出力にされてしまい、[['test']]のようになってリンクになりません。
要修正箇所はcvs:lib/make_link.php のlastmodified_add() とput_lastmodified() --
- http://blog.tokumaru.org/2011/11/php54htmlspecialchars.htmlに答えが書いてありました.htmlspecialchars()の非互換によるもので,確認のために同ペイジに書いてあるphpにパッチをあてる方法で正しく(!?)表示されるようになりました.パッチを当てるのはちょっと乱暴なので,同ペイジで提案されている「まとめてhtmlspecialchars関数を修正する方法」を採用するのがよろしかろうと思います.ただし,ページ内にあるアンカーをたどろうとすると,またapacheが500とのたまいます.これまたペイジの名称によってたどれるものと,そうでないものがあります.以下はたどれない例です.
http://192.168.0.4/(some where)/pukiwiki/pukiwiki.php?%A5%E9%A5%F3%A5%AD%A5%F3%A5%B0
ちょっと困りました. -- よっちい?
- たぶん関連。htmlspecialchars()のエイリアス関数htmlsc新設にともなうバグなど → BugTrack2/343 --
- お知らせありがとうございます,cvs版ではhtmlsc()が導入されているわけですね.そんなわけで,
#!/bin/sh
for i do
/bin/cat $i | /usr/bin/sed -e 's/htmlspecialchars/htmlsc/g' > $i.temp
/bin/mv $i.temp $i
done
としてlib/func.phpにhtmlsc()の実装を持ってきてみたりしました.これでphp-5.4.0RC1にパッチを当てずに表示は正しく出てくるようになったっぽいですが,うーん「たどれないリンクがある」は改善されないですね.... $flagsをphpのデフォルトにすれば良いのかな.... -- よっちい?
- htmlsc()適用忘れや定義ルール(コンバート時に置換)の修正忘れがないとして、スクリプトのエンコーディングと出力のエンコーディングを変えてあると文字化けするかも?携帯スキンのように最終段階で変換したりしてるだけなら問題ないんでしょうけど、define('SOURCE_ENCODING', 'EUC-JP');define('CONTENT_CHARSET', 'Shift_JIS');のようなパターンだとマズイかも --