Home arrow Extensions arrow Joomla! CMS

6月
08
2008

見えない文字(PHP inputfilter):Joomla!

diggに追加!

見えない文字に以前から惑わされていました。

以前にMovableType XML-RPCでエラーが出るとフォーラムで投稿があり、仮に対応したファイルでとりあえず間に合わせていたのですが、それをすこし掘り下げて見てみました。

これは、MovableType XML-RPCを使わなくても発生するのでみなさんの環境(Joomla!1.5でも発生します。)でもテスト可能です。ただし、一度登録してしまうとデータベースを書き戻さないと元に戻らないことに注意してください。もし、試されるならテスト環境にされた方が良いです。

まず保存後の記事のタイトルを見てください。

after_save

なにも問題なさそうですよね。プレビューしてみるとこんな感じです。(Joomla!1.5)

after_save_html

まったく問題ないように見えます。

では、保存前のタイトルを見てください。

before_save 

「“」と「”」が含まれています。これは「“」と「”」のことです。"ではないことに注意してください。htmlentityで書くと「“」「”」です。

このデータをphpMyAdminで表示しても「Example」の前と後には何も表示されません。ところが、これをブログエディタで取り込むとエラーになります。それは、UTF-8で許されていない文字を使用しているというエラーです。

Joomla!は、いろいろなライブラリで構成されています。この中にinputfilterというライブラリ

  • Jooml!1.5では、Root/libraries/phpinputfilter/inputfilter.php
  • Joomla!1.0.xでは、Root/includes/phpInputFilter/class.inputfilter.php

は、Joomla!の中で適切なクリーニングとサニタイズを行うために重要な役割をしています。これは、Joomla!1.5でも同じです。コンテンツを保存するとこのinputfilterが適切にクリーニングをしてくれるのですが、どうもこのライブラリの基本設定をUTF-8で使う場合は変更しなければならないのではないかと思うのです。基本設定が、ISO-8859-1となっているのでUTF-8の数値文字の場合適切にクリーニング・サニタイズされないのではないかと思います。

そのinputfilterの設定を変更して保存してみるとこうなります。

after_utf8

ちゃんと保存され、表示されているのがわかります。※このテスト環境は、PHP5以上です。

これは、極まれな例なので普通に使っているときは遭遇しない問題かもしれません。ですが、ソースをコピーしたりしたとき、元のソースが数値文字となっていた場合は注意しなければなりません。UTF-8をデフォルトとしているユーザー(JP版もしくは、Joomla!1.5ならほとんどが該当ユーザーです。)ならばその数値文字があらぬ文字に変換されてしまいます。また、その文字はphpMyAdminで保存しなおしても消すことはできません。SQLをエクスポートし、該当する場所を正常な文字に書き換え、インポートしないと消すことはできません。

これは、intortext, fulltextは保存時にinputfilterを通りませんが、title, title alias, metakey, metadescriptionは、inputfilterによって処理されるので注意が必要です。

その、inputfilterの該当部分ですが、PHPのhtml_entity_decode関数を使っている部分です。ですが、この関数は、PHP5より下位バージョンの場合マルチバイトの文字セットをサポートしていないようです。なのでPHP4.xな場合、UTF-8と指定してもISO-8859-1で処理されてしまうため、同じ問題が発生します。PHP5以上の方はISO-8859-1と指定している部分をUTF-8に変更すれば解消されます。そうでない方は、PHPのバージョンを5以上に切り替えるか、PHP Manualを参考に自身で独自のメソッドを加えるか、Joomla!で対応されるのを待つのかをしなければならないのではないでしょうか。

after_save_sql これは、一度保存されてしまうと気づきにくい問題です。データをSQLでエクスポートしてテキストエディタで表示しても半角スペースにしか見えませんし、そのままブラウザで表示しても表示されません。文字の実態になっていないのです。

いろいろ検索してみましたが、Joomla!に関しては具体的な対策をされているものは私は見つけることができませんでした。

PHPのマニュアルに投稿されているメソッドを使って(借りて)変更するとすれば、例えば以下の例のように変更すればPHP4でも可能です。※確実かどうかは検証しているわけではありません。

	function decode($source)
	{
		// url decode
		if((int)PHP_VERSION < 5){
			$source = InputFilter::utf8_html_entity_decode($source);
		} else {
			$source = html_entity_decode($source, ENT_QUOTES, "UTF-8");
		}
		// convert decimal
		$source = preg_replace('/&#(\d+);/me', "chr(\\1)", $source); // decimal notation
		// convert hex
		$source = preg_replace('/&#x([a-f0-9]+);/mei', "chr(0x\\1)", $source); // hex notation
		return $source;
	}

	function utf8_replaceEntity($result){
		$value = (int)$result[1];
		$string = '';

		$len = round(pow($value,1/8));

		for($i=$len;$i>0;$i--){
			$part = ($value & (255>>2)) | pow(2,7);
			if ( $i == 1 ) $part |= 255<<(8-$len);

			$string = chr($part) . $string;

			$value >>= 6;
		}

		return $string;
	}

	function utf8_html_entity_decode($string){
		return preg_replace_callback( '/&#([0-9]+);/u', array('InputFilter', 'utf8_replaceEntity'), $string );
	}

どういう場合に問題が生じるか

  • 数値文字をタイトルやタイトルエイリアスなどに入力してしまった場合、XML-RPCなどでUTF-8な通信を行った場合エラーが発生します。
  • XML-RPCでISO-8859-1で解釈されない文字をタイトルやタイトルエイリアス、メタキー、メタデスクリプションなどとして送信し、Joomla!のデフォルトのメソッドを利用し保存してしまうとその記事を取得するときにエラーが発生します。

と、現状これだけかもしれないのですがこれが元で大きな問題になることがあるのかもしれません。

MovableType XML-RPCプラグインでは現バージョンでは対応していないのでJoomla!が対応していないものにはクリーニングとサニタイズを独自に対応させないといけないようです。Joomla!が対応してくれると良いのですが・・・。

 

Related Articles

Web Links
ここではJoomla! Powerd Sitesをご紹介しています。※説明文は、リンク先サイトのmeta descriptionです。 このサイトは、CMS(コンテンツ・マネジメント・システム)で...
SQLインジェクション解析 iLogScanner : IPAから無償ツール
ITproの記事でIPAからSQLインジェクション攻撃をログから検出してくれる無償ツールが公開されたとあったので早速試してみた。 はじめはそのソフトがダウンロードできるものかと思っていたが、ブラウザ...
複数のJavascript、複数のスタイルシートを結合する
Joomla!にインストールするエクステンションが増えてくるとロードするJavascriptや、スタイルシートが次第に増えてきます。ヘッダ部分がかなり頭でっかちになってしまっているJoomla!サイト...
Joomla!1.5.4がリリースされています
いつものようにhttp://demo.joomler.netを上書きアップデートしました。 アップデート方法は、以前に記事にしたのと同じです。(かなり私はショートカットしていますが) 今回の...
コンテンツを分けないと:Joomler!.net
自分で見ていてもうちのサイトって見づらい。 昨日もエクステンションのインストール方法はどこに書いてあるのかと質問がメールで来ていて、自分で自分のサイトを探しましたよ。 「確か書いたよなぁ~。」っと...
SyntaxHighlighter : Windows Live Writer プラグイン
Windows Live WriterのプラグインSyntaxHightlighterを使うととても便利です。Joomla!にうちのSyntaxHighlighterプラグインをインストールしてお...
カテゴリの追加と移動:Joomla!
Joomla!って本当に便利ですね。 先日カスタムテンプレートを公開しましたが、docmanではカテゴリを作成していたのですが、エクステンションメニューにテンプレートのカテゴリを作成していなかったの...
MovableType XML-RPCを一部アップデートしました
今回は、Joomla!1.0.13用のEnglish版のみです。 環境は人によって異なるので面倒ですね。決まった環境で作成するのなら楽ですが・・・。今回は、ロシア語のサイトだと動かないと問い合わせが...
コンポーネント作成で参考になる(シンプル): Joomla!1.5
今日も、先日ブックマークしていたもので、Joomla!1.5のシンプルなコンポーネントの作成方法を解説されているサイトをご紹介します。 「Create MVC-model-view-controll...
Joomla!1.5の最新リビジョンで異なるDatabase Charsetを試してみた
Database CharsetをCP1251にし、以前にテストしたロシア語Joomla!1.0.xのデータベースをマイグレートしてみた。 Joomla!1.5では、1.0.xからデータベースをインポ...
ブログエディタでIntrotextとFulltextを分割する
1.5 Demo を作成しました
Meta Tag Generatorを消す : Joomla! 1.5
Joomla!1.0.xの管理で表示する記事一覧のソート : Hack
Joomla!1.5.2がリリースされています
Joomla!の Cache
コンポーネント作成で参考になる:Joomla! 1.0.x
Joomla!の正しいURIってわかりますか? : Extensions
mod WebLink Info : for Joomla!.15
最新版 1.0.5 for 1.0.x , 1.0.0 for Joomla!1.5 : QRcode

C_square_trans.png Components
Joomla! Extensions
M_square_trans.png Modules
Joomla! Extensions
P_square_trans.png Plugins
Joomla! Extensions
Templates
Joomla! Extensions
a_delphi.gif Delphi for PHP
Delphi for PHP related

for Mobile