プロジェクト

全般

プロフィール

Bug(バグ) #3931

Youichi Kimura さんが8年以上前に更新

h3. Overview (現象) 

 Zend_Validate_Hostname を使用する機能で .com, .biz, .cn ドメインのホスト名または URL がエラーになる。 

 具体的には、下記の機能で問題が発生する。 

  * OpenPNE.yml の @mail_smtp_host@ 
  ** 例: @smtp.gmail.com@ を使用したメール送信が行えない<pre><code class="yaml"> 
 mail_smtp_host: "smtp.gmail.com" 
 mail_smtp_config: 
   auth:       "login" 
   username: "*****@gmail.com" 
   password: “*****” 
   ssl:        "tls" 
   port:       587  
 </code></pre> 
  ** 発生するエラーの例: {{collapse(詳細を表示...) 
 <pre> 
 $ ./symfony openpne:send-daily-news --app=pc_frontend --trace 

                                         
   [Zend_Validate_Exception]               
   Internal error: DNS validation failed   
                                         

 Exception trace: 
   at /home/upsilon/git/openpne3/v3.6/lib/vendor/Zend/Validate/Hostname.php:365 
  Zend_Validate_Hostname->isValid at /home/upsilon/git/openpne3/v3.6/lib/vendor/Zend/Validate.php:94 
  Zend_Validate->isValid at /home/upsilon/git/openpne3/v3.6/lib/vendor/Zend/Mail/Protocol/Abstract.php:133 
  Zend_Mail_Protocol_Abstract->__construct at /home/upsilon/git/openpne3/v3.6/lib/vendor/Zend/Mail/Protocol/Smtp.php:156 
  Zend_Mail_Protocol_Smtp->__construct at /home/upsilon/git/openpne3/v3.6/lib/vendor/Zend/Mail/Protocol/Smtp/Auth/Login.php:76 
  Zend_Mail_Protocol_Smtp_Auth_Login->__construct at /home/upsilon/git/openpne3/v3.6/lib/vendor/Zend/Mail/Transport/Smtp.php:196 
  Zend_Mail_Transport_Smtp->_sendMail at /home/upsilon/git/openpne3/v3.6/lib/vendor/Zend/Mail/Transport/Abstract.php:348 
  Zend_Mail_Transport_Abstract->send at /home/upsilon/git/openpne3/v3.6/lib/vendor/Zend/Mail.php:936 
  Zend_Mail->send at /home/upsilon/git/openpne3/v3.6/lib/util/opMailSend.class.php:218 
  opMailSend::execute at /home/upsilon/git/openpne3/v3.6/lib/util/opMailSend.class.php:156 
  opMailSend::sendTemplateMail at /home/upsilon/git/openpne3/v3.6/lib/task/openpneSendDailyNewsTask.class.php:112 
  openpneSendDailyNewsTask->sendDailyNews at /home/upsilon/git/openpne3/v3.6/lib/task/openpneSendDailyNewsTask.class.php:43 
  openpneSendDailyNewsTask->execute at /home/upsilon/git/openpne3/v3.6/lib/vendor/symfony/lib/task/sfBaseTask.class.php:68 
  sfBaseTask->doRun at /home/upsilon/git/openpne3/v3.6/lib/vendor/symfony/lib/task/sfTask.class.php:97 
  sfTask->runFromCLI at /home/upsilon/git/openpne3/v3.6/lib/vendor/symfony/lib/command/sfSymfonyCommandApplication.class.php:76 
  sfSymfonyCommandApplication->run at /home/upsilon/git/openpne3/v3.6/lib/vendor/symfony/lib/command/cli.php:20 
  include at /home/upsilon/git/openpne3/v3.6/symfony:14 
 </pre> 
 }} 
  * opOpenSocialPlugin のアプリ追加 
  ** 例: 管理画面の「アプリ追加」(/pc_backend_dev.php/opOpenSocialPlugin/add) で @Gadget XML URL@ に @gist.github.com@ などのドメインの URL を指定するとエラーになる 

 この不具合は OpenPNE *3.4.x* および *3.6.x* のみで発生する。 

 h3. Causes (原因) 

 #205 で起きた問題の修正のために、@Zend_Validate_Hostname@ に対して @3.7.0@ 以降とそれ以前で異なる修正が行われた。 
 この修正により OpenPNE 3.6.x には commit:fbdbb216 の修正が行われたが、「最新の安定版で配布されている Zend/Validate/Hostname/*.php とほぼ近い挙動になるようなクラスファイル」が正しく機能しなかったため今回の不具合が起きた。 

 #205-6 より引用: 
 > 次の方針で実装します。 
 >  
 >    * OpenPNE 3.7.0      : 同梱する ZendFramework の最新の安定版にアップデートします 
 >    * OpenPNE 3.6 以前 : ZendFramework の最新の安定版に存在する Zend/Validate/Hostname/*.php に対応するファイルが同梱している ZendFramework に存在していなければ、最新の安定版で配布されている Zend/Validate/Hostname/*.php とほぼ近い挙動になるようなクラスファイルを追加するという暫定的な対処をおこないます 

 h4. *.biz, *.cn ドメインの場合に発生するエラー 

 <pre> 
 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 
 </pre> 

 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 は複数に分割された正規表現パターンを使用してドメイン名をチェックしているため今回のような問題は発生していない。 

 h4. *.com ドメインの場合に発生するエラー 

 <pre> 
 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 
 </pre> 

 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 までの範囲は Unicode のサロゲートペアの high surrogates および low surrogates のために確保された領域であり、これらの領域では 2 つの符号単位で 1 文字として扱うためいずれか単体で正規表現パターンにマッチすることはない。 
 例えば、*.com ドメインでの使用が認められている "リュキア文字":http://www.unicode.org/charts/PDF/U10280.pdf はサロゲートペアで表される領域の文字であり、@LYCIAN LETTER A@ であれば U+D800 U+DE80 の組で 1 文字として扱われるため @/\x{D800}-\x{DFFF}/u@ のような正規表現パターンを用いてもマッチすることはない(サロゲートペアは U+10000 以降のコードポイントで表され、@LYCIAN LETTER A@ の場合は U+10280 であるため @/\x{10280}/u@ であればマッチする) 

 <pre> 
 $ 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) 
 </pre> 

 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 以降の動作と同じである) 

 h3. Way to fix (修正内容) 

 修正内容を記入

戻る