[PHP-dev 1488] mbstring の文字列変換、文字エンコーディング検出の関連の問題について

View: New views
11 Messages — Rating Filter:   Alert me  

[PHP-dev 1488] mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by komura-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

komura です。

mbstring の文字列変換、文字エンコーディング検出の関連でいくつか気になる問題を
見つけましたので、参考までに Patch を作成してみました(4. を除く)。

PHP 5.3.0 で確認した挙動ですが、PHP 5.2.10 以前でも同じです。
いくつかは仕様かもしれませんが・・・。

1. mb_convert_encoding() で UTF-16(Little Endian) の文字列を変換すると結果が
   壊れる

   UTF-16(Little Endian) で作成した文字列を変換すると、1文字目が壊れます。
   Shift_JIS や EUC-JP に変換した場合でも、1文字目が壊れます。
   変換元文字列が UTF-16(Big Endian) の場合は問題ありません。

   * 再現コード
     // UTF-16(Little Endian) で「テスト」を UTF-16 から UTF-16 へ変換
     $str = "\xFF\xFE\xC6\x30\xB9\x30\xC8\x30";
     var_dump( bin2hex( mb_convert_encoding( $str, "UTF-16", "UTF-16" ) ) );

   * 結果
     string(16) "feffffc630b930c8"
                     ^^←違い
   * 期待する結果
     string(16) "feff30c630b930c8"

   * Patch
     php530_mbfilter_utf16_invalid_conversion.patch

   BOM(\xfe\xff) の次の1バイトが必ず \xff になります。

   期待する結果としては、エンディアンが変換されない "fffec630b930c830" の方が
   都合が良いかもしれませんが、UTF-16 から UTF-16 への変換は、変換元文字列が
   UTF-16(Little Endian) の場合、UTF-16(Big Endian) に変換されます。

2. mb_detect_encoding() で、第3引数(strict)を TRUE にしている場合、最後の
   1文字(バイト)が不正でも不正にならない

   mb_detect_encoding() で、第3引数(strict)を TRUE を指定している場合、
   先行バイト(例:Shift_JIS の \x81)に続く文字列が不正な場合、返り値は
   不正になります。

   しかし、最後の1文字(バイト)が先行バイトのみで終わるバイト列の場合、
   不正になりません。例は Shift_JIS ですが、EUC-JP や UTF-8 でも同様です。

   * 再現コード
     // \x81 で終っているため、不正(false)を期待
     var_dump( mb_detect_encoding( "A\x81", "SJIS", TRUE ) );

   * 結果
     string(4) "SJIS"

   * 期待する結果
     bool(false)

   * Patch
     php530_mbfilter_mb_detect_encoding_strict.patch

   mb_detect_encoding( "\x81 A", "SJIS", TRUE ) のようにすれば不正(false)に
   なります。最後の1文字(バイト)が不正な場合に関数が false を返さないという
   問題です。

3. mb_detect_encoding() で、strict 指定しているのに、一部の不正な UTF-8 の
   文字列が不正にならない

   2. の Patch を当てた場合に顕在化する問題です。mb_detect_encoding() で、
   第3引数(strict)を TRUE にしている場合でも、UTF-8 の不正な文字列
   (\xc0\x00, \xd0\x00, ..., \xfd\x00) が不正になりません。

   * 再現コード
     var_dump( mb_detect_encoding( "\xc0\x00", "UTF-8", TRUE );

   * 結果
     string(5) "UTF-8"

   * 期待する結果
     bool(false)

   * Patch
     php530_mbfilter_utf8_pass_invalid_character.patch

4. mb_check_encoding() で UTF-16(Little Endian) を判定すると、必ず false を
   返す

   mb_check_encoding() では、変換前の文字列と変換後の文字列が同じだった場合
   に true を返しますが、内部的に、UTF-16(Little Endian) が UTF-16(Big Endian)
   に変換されるため、必ず false になります。

   UTF-16(Big Endian) や、UTF-16(Little Endian) の文字列を UTF-16LE として
   判定した場合には、問題ありません。

   * 再現コード
     // UTF-16(Little Endian) で「テスト」
     $str = "\xFF\xFE\xC6\x30\xB9\x30\xC8\x30";
     var_dump( mb_check_encoding( $str, "UTF-16" ) );

   * 結果
     bool(false)

   * 期待する結果
     bool(true)

   * Patch
     作成していません

--
komura <komura.db2r1e@...>

[php530_mbfilter_utf16_invalid_conversion.patch]

diff -ur php-5.3.0.orig/ext/mbstring/libmbfl/filters/mbfilter_utf16.c php-5.3.0/ext/mbstring/libmbfl/filters/mbfilter_utf16.c
--- php-5.3.0.orig/ext/mbstring/libmbfl/filters/mbfilter_utf16.c 2003-08-23 15:18:36.000000000 +0900
+++ php-5.3.0/ext/mbstring/libmbfl/filters/mbfilter_utf16.c 2009-08-11 18:07:08.000000000 +0900
@@ -151,6 +151,7 @@
  } else {
  filter->status = 0x100; /* little-endian */
  }
+ filter->cache = 0;
  CK((*filter->output_function)(0xfeff, filter->data));
  } else if (n >= 0xd800 && n < 0xdc00) {
  filter->cache = ((n & 0x3ff) << 16) + 0x400000;


[php530_mbfilter_mb_detect_encoding_strict.patch]

diff -ur php-5.3.0.orig/ext/mbstring/libmbfl/mbfl/mbfilter.c php-5.3.0/ext/mbstring/libmbfl/mbfl/mbfilter.c
--- php-5.3.0.orig/ext/mbstring/libmbfl/mbfl/mbfilter.c 2009-02-15 16:11:04.000000000 +0900
+++ php-5.3.0/ext/mbstring/libmbfl/mbfl/mbfilter.c 2009-08-11 21:05:21.000000000 +0900
@@ -622,7 +622,7 @@
  if (!encoding) {
  for (i = 0; i < num; i++) {
  filter = &flist[i];
- if (!filter->flag) {
+ if (!filter->flag && (!strict || !filter->status)) {
  encoding = filter->encoding;
  break;
  }


[php530_mbfilter_utf8_pass_invalid_character.patch]

diff -ur php-5.3.0.orig/ext/mbstring/libmbfl/filters/mbfilter_utf8.c php-5.3.0/ext/mbstring/libmbfl/filters/mbfilter_utf8.c
--- php-5.3.0.orig/ext/mbstring/libmbfl/filters/mbfilter_utf8.c 2009-02-24 22:19:09.000000000 +0900
+++ php-5.3.0/ext/mbstring/libmbfl/filters/mbfilter_utf8.c 2009-08-11 21:05:21.000000000 +0900
@@ -220,7 +220,7 @@
  if (c < 0x80) {
  if (c < 0) {
  filter->flag = 1; /* bad */
- } else if (c != 0 && filter->status) {
+ } else if (filter->status) {
  filter->flag = 1; /* bad */
  }
  filter->status = 0;


_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev

[PHP-dev 1489] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by Moriyoshi Koizumi-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

小泉です。

レポートありがとうございます。

基本的に送っていただいたパッチをそのままコミットしていいと思うのですが、ダブルチェックしたいのでちょっとお時間をください。

2009/8/16 komura <komura.db2r1e@...>:
> 1. mb_convert_encoding() で UTF-16(Little Endian) の文字列を変換すると結果が
>   壊れる
>
>   UTF-16(Little Endian) で作成した文字列を変換すると、1文字目が壊れます。
>   Shift_JIS や EUC-JP に変換した場合でも、1文字目が壊れます。
>   変換元文字列が UTF-16(Big Endian) の場合は問題ありません。

エンコーディング名 "UTF-16" は "UTF-16BE" や "UTF-16LE" と違い、BOM
によってエンディアンを判定します。手元で試したところ、BOM が \xff \xfe でも \xfe \xff
でも問題が発生することが確認できました。

> 2. mb_detect_encoding() で、第3引数(strict)を TRUE にしている場合、最後の
>   1文字(バイト)が不正でも不正にならない

修正はパッチの通りかと思います。

> 3. mb_detect_encoding() で、strict 指定しているのに、一部の不正な UTF-8 の
>   文字列が不正にならない
>
>   2. の Patch を当てた場合に顕在化する問題です。mb_detect_encoding() で、
>   第3引数(strict)を TRUE にしている場合でも、UTF-8 の不正な文字列
>   (\xc0\x00, \xd0\x00, ..., \xfd\x00) が不正になりません。

まさか、と思ってパッチを見たらその通りの問題で笑ってしまいました。該当箇所の c != 0 の意図がさっぱり分かりませんねぇ。

>
> 4. mb_check_encoding() で UTF-16(Little Endian) を判定すると、必ず false を
>   返す

これは先にも書きましたが、BOM を見てエンディアンを判定することによるものなので問題はないように思えます。
_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev

[PHP-dev 1490] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by komura-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

komura です。

お忙しい中、確認どうもありがとうございます。

On Wed, 19 Aug 2009 00:37:22 +0900
Moriyoshi Koizumi <mozo@...> wrote:

> 基本的に送っていただいたパッチをそのままコミットしていいと思うのですが、ダブルチェックしたいのでちょっとお時間をください。

私は急いでいませんので、時間のあるときに検証いただけましたら幸いです。


> 1. mb_convert_encoding() で UTF-16(Little Endian) の文字列を変換すると結果が
>   壊れる
>
>   UTF-16(Little Endian) で作成した文字列を変換すると、1文字目が壊れます。
>   Shift_JIS や EUC-JP に変換した場合でも、1文字目が壊れます。
>   変換元文字列が UTF-16(Big Endian) の場合は問題ありません。
>
> エンコーディング名 "UTF-16" は "UTF-16BE" や "UTF-16LE" と違い、BOM
> によってエンディアンを判定します。手元で試したところ、BOM が \xff \xfe でも \xfe \xff
> でも問題が発生することが確認できました。

以下のテストコードで、BOM 付きの Big Endian では、正しく変換されている
ように見えましたので、問題ないと書いたのですが、私の勘違いでしょうか?

 <?php
 // "テスト"(UTF-16 BOM 付き Little Endian)
 $str = "\xFF\xFE\xC6\x30\xB9\x30\xC8\x30";
 echo "* UTF-16(Little Endian) -> UTF-16: ";
 var_dump( bin2hex( mb_convert_encoding( $str, "UTF-16", "UTF-16" ) ) );

 // "テスト"(UTF-16 BOM 付き Big Endian)
 $str = "\xFE\xFF\x30\xC6\x30\xB9\x30\xC8";
 echo "* UTF-16(Big Endian)    -> UTF-16: ";
 var_dump( bin2hex( mb_convert_encoding( $str, "UTF-16", "UTF-16" ) ) );

 結果(PHP 5.3.0)
 ---------------
 * UTF-16(Little Endian) -> UTF-16: string(16) "feffffc630b930c8"  <- 壊れる
 * UTF-16(Big Endian)    -> UTF-16: string(16) "feff30c630b930c8"  <- 問題なし


> > 4. mb_check_encoding() で UTF-16(Little Endian) を判定すると、必ず false を
> >   返す
>
> これは先にも書きましたが、BOM を見てエンディアンを判定することによるものなので問題はないように思えます。

すみません。これは、少し複雑な問題です。
実際には、1. の Patch を適用しても、以下の結果になります。

 <?php
 // "テスト"(UTF-16 BOM 付き Little Endian)
 $str = "\xFF\xFE\xC6\x30\xB9\x30\xC8\x30";
 echo "* UTF-16(Little Endian): ";
 var_dump( mb_check_encoding( $str, "UTF-16" ) );

 // "テスト"(UTF-16 BOM 付き Big Endian)
 $str = "\xFE\xFF\x30\xC6\x30\xB9\x30\xC8";
 echo "* UTF-16(Big Endian)   : ";
 var_dump( mb_check_encoding( $str, "UTF-16" ) );

 結果(PHP 5.3.0)
 ---------------
 * UTF-16(Little Endian): bool(false) <- bool(true) になって欲しい
 * UTF-16(Big Endian)   : bool(true)  <- 問題なし


補足しますと、mb_check_encoding( $str, "UTF-16" ) を実行した場合、
UTF-16 -> UTF-16 の変換を行い、その結果が、元の $str と同一かどうかで
結果を判定します。

この変換を行うと、UTF-16(BOM 付き Little Endian)の文字列は、
Big Endianに変換され、変換後は元の文字列に戻りません。
ただし、以下はどちらも UTF-16 としては正しい文字列です。

 変換前(UTF-16 BOM 付き Little Endian): "fffec630b930c830"
 変換後(UTF-16 BOM 付き Big Endian)   : "feff30c630b930c8"


このため、mb_check_encoding() では、UTF-16(BOM 付き Little Endian)の
文字列は、false になります。この問題を修正するには、UTF-16 -> UTF-16
の変換で、エンディアンを保持する必要があります。

ただ、UTF-16 の文字列を mb_check_encoding() で判定したいという状況は
あまり考えられません。今後、ICU ベースに移行する予定もありますし、
無理に修正する必要はないように思います。

--
komura <komura.db2r1e@...
_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev

[PHP-dev 1491] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by Moriyoshi Koizumi-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

小泉です。

2009/8/20 komura <komura.db2r1e@...>:

>> 1. mb_convert_encoding() で UTF-16(Little Endian) の文字列を変換すると結果が
>>   壊れる
>>
>>   UTF-16(Little Endian) で作成した文字列を変換すると、1文字目が壊れます。
>>   Shift_JIS や EUC-JP に変換した場合でも、1文字目が壊れます。
>>   変換元文字列が UTF-16(Big Endian) の場合は問題ありません。
>>
>> エンコーディング名 "UTF-16" は "UTF-16BE" や "UTF-16LE" と違い、BOM
>> によってエンディアンを判定します。手元で試したところ、BOM が \xff \xfe でも \xfe \xff
>> でも問題が発生することが確認できました。
>
> 以下のテストコードで、BOM 付きの Big Endian では、正しく変換されている
> ように見えましたので、問題ないと書いたのですが、私の勘違いでしょうか?

いえ、私の勘違いでした。余計なお手間をおかけしてすみません。

ところで、関連する別の問題を発見してしまいました。本来であれば U+FEFF は先頭にあるときのみ BOM
としての役割を果たすため、挙動としては明らかにバグなのですが、コード列の中のいずれの箇所でも U+FFFE が出現すると、U+FEFF
が出力された後、エンディアンが切り替わってしまうのです。

<?php
var_dump(bin2hex(mb_convert_encoding("\xfe\xff\xff\xfe\xfe\xff\x41\x00\x42\x00\x41\x00",
"UTF-16BE", "UTF-16")));
?>

パッチ適用後の出力結果:
string(20) "fefffeff004100420041"

ちなみにパッチ適用前は以下のようになっていました:
string(20) "fefffefffefffefffeff"


>> > 4. mb_check_encoding() で UTF-16(Little Endian) を判定すると、必ず false を
>> >   返す
>>
>> これは先にも書きましたが、BOM を見てエンディアンを判定することによるものなので問題はないように思えます。
>
> すみません。これは、少し複雑な問題です。
> 実際には、1. の Patch を適用しても、以下の結果になります。
(snip)
> このため、mb_check_encoding() では、UTF-16(BOM 付き Little Endian)の
> 文字列は、false になります。この問題を修正するには、UTF-16 -> UTF-16
> の変換で、エンディアンを保持する必要があります。

すみません、言葉足らずで、斜め読みでよく問題を理解していないのではないかと疑われても仕方ないのですが、
これについては、仕様、という認識です。

# いろいろな意見があるかと思いますが、個人的には、mb_check_encoding() 自体の有用性を疑っています。

なお、ICU への移移行は決まったわけではないので、保守は続けていきます。
_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev

[PHP-dev 1492] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by komura-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

komura です。

On Thu, 20 Aug 2009 02:11:39 +0900
Moriyoshi Koizumi <mozo@...> wrote:

> ところで、関連する別の問題を発見してしまいました。本来であれば U+FEFF は先頭にあるときのみ BOM
> としての役割を果たすため、挙動としては明らかにバグなのですが、コード列の中のいずれの箇所でも U+FFFE が出現すると、U+FEFF
> が出力された後、エンディアンが切り替わってしまうのです。

確認しました。この問題は見落としていました。
場当たり的なパッチは作成してみたのですが、あまり検証していませんので、
もう少し検証してから投稿するか考えます(既に小泉さんがパッチを書いて
おられるかもしれませんが)。

結果としては、以下のように、エンディアンが変更されずに、出力される
のが正しいのでしょうか?

<?php
var_dump(bin2hex(mb_convert_encoding("\xfe\xff\xff\xfe\x41\x00\x42\x00\x41\x00",
"UTF-16BE", "UTF-16")));
----
結果
string(20) "fefffffe410042004100"

それとも、0xfffe が BOM の位置以外で出現した場合は、不正文字列として
削除すべきでしょうか?
手元の iconv では削除するようです。ただ、iconv も本件と同じような問題
があるような気がします。

var_dump(bin2hex(iconv("UTF-16", "UTF-16BE",
"\xfe\xff\xff\xfe\x41\x00\x42\x00\x41\x00")));
----
結果
string(16) "fffe410042004100"


> >> > 4. mb_check_encoding() で UTF-16(Little Endian) を判定すると、必ず false を
> >> >   返す
...
> すみません、言葉足らずで、斜め読みでよく問題を理解していないのではないかと疑われても仕方ないのですが、
> これについては、仕様、という認識です。

了解しました。仕様ということで問題ないと思います。

 
> # いろいろな意見があるかと思いますが、個人的には、mb_check_encoding() 自体の有用性を疑っています。

これには同意します。
mb_check_encoding() 以外の方法で、文字エンコーディングの妥当性を正しく
検証できる手段があれば良いのですが・・・。

mb_check_encoding() の代替手段として、mb_detect_encoding() が使えないか
と調べたことがあったのですが、使えないという結論に至りました。今回、
報告した問題の他にも、UTF-16 など、一部の文字エンコーディングが判定
できない問題、UTF-8 で、冗長表現や、サロゲートペア領域を有効と判定
する問題など、多くの問題があるように思います。

現状では、文字エンコーディングを正確に判定したい場合は、正規表現を
使うのが妥当だろうと思います。


> なお、ICU への移行は決まったわけではないので、保守は続けていきます。

分かりました。ICU への移行には期待しています。

--
komura <komura.db2r1e@...>
_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev

[PHP-dev 1493] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by Yasuo Ohgaki :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

大垣です。

PHPの脆弱性でもmb_check_encodingを使っていれば回避出来た脆弱性
が幾つもあります。

> # いろいろな意見があるかと思いますが、個人的には、mb_check_encoding() 自体の有用性を疑っています。

ちなみに有用性を疑っているのは使い方の面でしょうか?

これがあるだけエンコーディングチェックに関しては他の言語より随分
ましとは思っています。海外アプリでは全く使われていないので無用の
長物になっている、という意見であれば同じです。

--
Yasuo Ohgaki
yohgaki@...
_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev

[PHP-dev 1494] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by Yasuo Ohgaki :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

2009/08/29 10:02 に Yasuo Ohgaki<yohgaki@...> さんは書きました:
> これがあるだけエンコーディングチェックに関しては他の言語より随分
> ましとは思っています。海外アプリでは全く使われていないので無用の
> 長物になっている、という意見であれば同じです。

ちょっと不正確ですね。mb_check_encodingを使っていないのは、海外ア
プリに限らず日本のアプリでもほとんど見ないです。

エンコーディングをチェックするだけで随分安心感が向上するのですが...

--
Yasuo Ohgaki
yohgaki@...
_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev

[PHP-dev 1496] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by komura-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

komura です。

遅くなりましたが、作成したパッチを検証してみました。
とりあえず、大きな問題はなさそうに思いましたので、添付して投稿します。


> > ところで、関連する別の問題を発見してしまいました。本来であれば U+FEFF は先頭にあるときのみ BOM
> > としての役割を果たすため、挙動としては明らかにバグなのですが、コード列の中のいずれの箇所でも U+FFFE が出現すると、U+FEFF
> > が出力された後、エンディアンが切り替わってしまうのです。

パッチでは、エンディアンの切り替えは最初だけにしてみました。
結果は以下のようになります。

$ php 'var_dump( bin2hex( mb_convert_encoding(
 "\xfe\xff\xff\xfe\x41\x00\x42\x00\x41\x00", "UTF-16BE", "UTF-16" ) ) );'

パッチ適用前: string(20) "fefffeffff4100420041"
パッチ適用後: string(20) "fefffffe410042004100"


> それとも、0xfffe が BOM の位置以外で出現した場合は、不正文字列として
> 削除すべきでしょうか?
> 手元の iconv では削除するようです。ただ、iconv も本件と同じような問題
> があるような気がします。
>
> var_dump(bin2hex(iconv("UTF-16", "UTF-16BE",
> "\xfe\xff\xff\xfe\x41\x00\x42\x00\x41\x00")));
> ----
> 結果
> string(16) "fffe410042004100"
上記の BOM に関する件と iconv() の挙動については、私が勘違いです。
UTF-16BE は BOM を付けてはならないため、iconv() の結果としては上記
で正しい動作になっています。
上記の場合は、BOM があるのかないのか判断できないような気がしますが・・・。


RFC2781 では、UTF-16BE と UTF-16LE は BOM は使用不可となっています。
mb_convert_encoding() では、UTF-16BE および、UTF-16LE への変換では
BOM が残りますので、この挙動の方がおかしいということなると思います。

今回のパッチでは、BOM 関連の処理は変更していません。
UTF-16 の変換で文字列が壊れるという当初の問題と、途中で U+FEFF が
出現した場合に、エンディアンが切り替わるという問題のみへの対処です。

--
komura <komura.db2r1e@...>

[php530_mbfilter_utf16_invalid_conversion_2.patch]

diff -ur php-5.3.0.orig/ext/mbstring/libmbfl/filters/mbfilter_utf16.c php-5.3.0/ext/mbstring/libmbfl/filters/mbfilter_utf16.c
--- php-5.3.0.orig/ext/mbstring/libmbfl/filters/mbfilter_utf16.c 2003-08-23 15:18:36.000000000 +0900
+++ php-5.3.0/ext/mbstring/libmbfl/filters/mbfilter_utf16.c 2009-08-29 14:04:29.000000000 +0900
@@ -145,12 +145,13 @@
  }
  n |= filter->cache & 0xffff;
  filter->status &= ~0xff;
- if (n == 0xfffe) {
- if (endian) {
+ if (!(filter->status & 0xff0000) && (n == 0xfffe || n == 0xfeff)) {
+ if (n == 0xfeff) {
  filter->status = 0; /* big-endian */
  } else {
  filter->status = 0x100; /* little-endian */
  }
+ filter->cache = 0;
  CK((*filter->output_function)(0xfeff, filter->data));
  } else if (n >= 0xd800 && n < 0xdc00) {
  filter->cache = ((n & 0x3ff) << 16) + 0x400000;
@@ -169,6 +170,7 @@
  filter->cache = 0;
  CK((*filter->output_function)(n, filter->data));
  }
+ filter->status |= 0x10000;
  break;
  }
 


_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev

[PHP-dev 1497] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by Moriyoshi Koizumi-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

小泉です。

2 つの観点から有用性を疑っています。

まず、概念的な部分です。エンコーディングをバリデートするという発想は正しいですが、mb_check_encoding()
は、ユーザに簡易な方法で正しい対処をさせるという手段としては不十分かと思います。不正なバイト列が発見された場合にどう処理すればいいのか、というところが見えてこないからです。

encoding_translation
を使い、毎度変換を行うことで、不正な文字をすべてフィルタできます。mb_check_encoding()
も結局は内部的に変換を行うことで不正なエンコーディングかをチェックしているわけですから、この方法で十分な処置が行えるかと思います。

もしよりきめ細かい対処が必要な場合は、自分でバリデート用の関数を用意すればいいですし、これをあえて mbstring
モジュールとして提供する必要はないかと思われます。

また、mb_check_encoding() は、全引数を省略したときの挙動にバグがあり、これを正しく直すことは困難です。

もう一点は、現在の mb_check_encoding()
自体の仕様に対するものです。正しい形式でエンコードされていればラウンドトリップが可能だという前提で処理を行っていますが、これは常に正しいわけではないというのが今回
komura さんの指摘してくださったポイントかと思います。正しくバリデートを行うためには、libmbfl 自体に手を入れる必要があります。

2009/8/29 Yasuo Ohgaki <yohgaki@...>:

> 大垣です。
>
> PHPの脆弱性でもmb_check_encodingを使っていれば回避出来た脆弱性
> が幾つもあります。
>
>> # いろいろな意見があるかと思いますが、個人的には、mb_check_encoding() 自体の有用性を疑っています。
>
> ちなみに有用性を疑っているのは使い方の面でしょうか?
>
> これがあるだけエンコーディングチェックに関しては他の言語より随分
> ましとは思っています。海外アプリでは全く使われていないので無用の
> 長物になっている、という意見であれば同じです。
>
> --
> Yasuo Ohgaki
> yohgaki@...
> _______________________________________________
> PHP-dev mailing list
> PHP-dev@...
> http://ml.php.gr.jp/mailman/listinfo/php-dev
>
_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev

[PHP-dev 1498] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by Moriyoshi Koizumi-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

小泉です。

本件のパッチ作成ありがとうございます!
対応が本当に遅くなってすみません。

パッチはリリース間近の 5.2 ブランチを除き、すべてコミットされました。報告にとどまらず、パッチ作成までしていただいて大変感謝しています。

重ね重ねになりますが、ありがとうございました!

2009/8/30 komura <komura.db2r1e@...>:
> RFC2781 では、UTF-16BE と UTF-16LE は BOM は使用不可となっています。
> mb_convert_encoding() では、UTF-16BE および、UTF-16LE への変換では
> BOM が残りますので、この挙動の方がおかしいということなると思います。
>
> 今回のパッチでは、BOM 関連の処理は変更していません。
> UTF-16 の変換で文字列が壊れるという当初の問題と、途中で U+FEFF が
> 出現した場合に、エンディアンが切り替わるという問題のみへの対処です。

BOM が残ってしまう問題についても対処する必要があると考えますので、その部分を解消したパッチをコミットしたいと思います。



> --
> komura <komura.db2r1e@...>
>
> _______________________________________________
> PHP-dev mailing list
> PHP-dev@...
> http://ml.php.gr.jp/mailman/listinfo/php-dev
>
_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev

[PHP-dev 1499] Re: mbstring の文字列変換、文字エンコーディング検出の関連の問題について

by komura-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

komura です。

On Sat, 12 Sep 2009 06:28:09 +0900
Moriyoshi Koizumi <mozo@...> wrote:
> パッチはリリース間近の 5.2 ブランチを除き、すべてコミットされました。報告にとどまらず、パッチ作成までしていただいて大変感謝しています。
>
> 重ね重ねになりますが、ありがとうございました!

svn.php.net でコミットを確認しました。
お忙しい中、対応いただき、どうもありがとうございました。

> > 今回のパッチでは、BOM 関連の処理は変更していません。
> > UTF-16 の変換で文字列が壊れるという当初の問題と、途中で U+FEFF が
> > 出現した場合に、エンディアンが切り替わるという問題のみへの対処です。
>
> BOM が残ってしまう問題についても対処する必要があると考えますので、その部分を解消したパッチをコミットしたいと思います。

よろしくお願いします。
時間があれば、こちらでも見てみようと思います。

--
komura <komura.db2r1e@...>
_______________________________________________
PHP-dev mailing list
PHP-dev@...
http://ml.php.gr.jp/mailman/listinfo/php-dev