Bug(バグ) #3931
未完了Zend_Validate_Hostnameクラスで .com, .biz, .cn ドメインのホスト名がエラーになる
0%
説明
Overview (現象)¶
Zend_Validate_Hostname を使用する機能で .com, .biz, .cn ドメインのホスト名または URL がエラーになる。
この不具合は OpenPNE 3.4.x および 3.6.x のみで発生する。
具体的には、下記の機能で問題が発生する。
- OpenPNE.yml の
mail_smtp_host
- 例:
smtp.gmail.com
を使用したメール送信が行えないmail_smtp_host: "smtp.gmail.com" mail_smtp_config: auth: "login" username: "*****@gmail.com" password: "*****" ssl: "tls" port: 587
- 発生するエラーの例: 詳細を表示...
- 例:
- opOpenSocialPlugin のアプリ追加
- 例: 管理画面の「アプリ追加」(/pc_backend_dev.php/opOpenSocialPlugin/add) で
Gadget XML URL
にgist.github.com
などのドメインの URL を指定するとエラーになる
- 例: 管理画面の「アプリ追加」(/pc_backend_dev.php/opOpenSocialPlugin/add) で
Causes (原因)¶
#205 で起きた問題の修正のために、Zend_Validate_Hostname
に対して master ブランチと安定版ブランチで異なる修正が行われた。
#205-6 より引用:
次の方針で実装します。
- OpenPNE 3.7.0 : 同梱する ZendFramework の最新の安定版にアップデートします
- OpenPNE 3.6 以前 : ZendFramework の最新の安定版に存在する Zend/Validate/Hostname/*.php に対応するファイルが同梱している ZendFramework に存在していなければ、最新の安定版で配布されている Zend/Validate/Hostname/*.php とほぼ近い挙動になるようなクラスファイルを追加するという暫定的な対処をおこないます
この修正により OpenPNE 3.6.x には fbdbb216 の修正が行われたが、「最新の安定版で配布されている Zend/Validate/Hostname/*.php とほぼ近い挙動になるようなクラスファイル」が正しく機能しなかったため今回の不具合が起きた。
*.biz, *.cn ドメインの場合に発生するエラー¶
PHP Warning: preg_match(): Compilation failed: regular expression is too large at offset 156194 in /home/upsilon/git/openpne3/v3.6/lib/vendor/Zend/Validate/Hostname.php on line 358
source:lib/vendor/Zend/Validate/Hostname/Biz.php@fbdbb216 のパターンは 207,460 文字、 source:lib/vendor/Zend/Validate/Hostname/Cn.php@fbdbb216 のパターンは 156,176 文字と非常に巨大な正規表現パターンとなっており、このことがエラーの原因であると考えられる。
3.7.0 以降に対して修正された source:lib/vendor/Zend/Validate/Hostname/Biz.php@821abff4 は複数に分割された正規表現パターンを使用してドメイン名をチェックしているため今回のような問題は発生していない。
*.com ドメインの場合に発生するエラー¶
PHP Warning: preg_match(): Compilation failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 9800 in /home/upsilon/git/openpne3/v3.6/lib/vendor/Zend/Validate/Hostname.php on line 358
source:lib/vendor/Zend/Validate/Hostname/Com.php@fbdbb216 の正規表現パターンには \x{D800}-\x{DB7F}\x{DC00}-\x{DFFF}
が含まれており、この部分がサロゲートペアで使用する領域に該当するため上記のエラーが発生したと考えられる。
実際にこの部分を除去すると *.com ドメインのホスト名でエラーになる現象は起きなくなった。
(サロゲートペアを含むドメインは Zend_Validate_Hostname::isValid()
で false になるが、これは #205 の対応前および OpenPNE 3.7.0 以降の動作と同じである)
コードポイント U+D800 から U+DFFF までの範囲は UTF-16 でサロゲートペアの high surrogates および low surrogates のために確保された領域であり、これらの領域では high surrogates と low surrogates の 2 つの符号で 1 文字として扱うためいずれか単体が正規表現パターンにマッチすることはない。
例えば、*.com ドメインでの使用が認められている リュキア文字 はサロゲートペアで表される領域の文字であり、「𐊀」(LYCIAN LETTER A
) であれば UTF-16 では 0xD800 0xDE80 の組で 1 文字として扱われるが /[\x{D800}-\x{DFFF}]/u
のような正規表現パターンを用いてもどちらの符号にもマッチしない(サロゲートペアは U+10000 以降のコードポイントで表され、LYCIAN LETTER A
の場合は U+10280 であるため /\x{10280}/u
であればマッチする)
$ cat hoge.php <?php $str = mb_convert_encoding(pack('H*', 'D800DE80'), 'UTF-8', 'UTF-16BE'); var_dump(preg_match('/[\x{D800}-\x{DFFF}]/u', $str)); var_dump(preg_match('/\x{10280}/u', $str)); $ php hoge.php PHP Warning: preg_match(): Compilation failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 in /home/upsilon/git/openpne3/master/hoge.php on line 4 Warning: preg_match(): Compilation failed: disallowed Unicode code point (>= 0xd800 && <= 0xdfff) at offset 7 in /home/upsilon/git/openpne3/master/hoge.php on line 4 bool(false) int(1)
Way to fix (修正内容)¶
修正内容を記入
Youichi Kimura さんが8年以上前に更新
- 3.6 で発生するか を Unknown (未調査) から Yes (はい) に変更
- 3.8 で発生するか を Unknown (未調査) から No (いいえ) に変更