Developer's Blog

【Web】 PHPの正規表現での不具合

こんにちは。 Web 担当の真谷(シンガイ)です。
今回は PHP で作業を行っていた際に遭遇した予期しなかった不具合についてお話します。


ある JSON ファイルデータをチェックする機能を実装する際に、PHP 5.2 以上で標準で実装されている JSON 関数とは別に、5.2未満のバージョンの PHP でも正常に処理できるように Jsphon という PHP ライセンスの JSON ライブラリを使用していました。
当然のように標準 JSON 関数の場合は正常に動作をしたのですが

$result = json_decode($json_data);

Jsphon の方は、Segmentation Fault が発生し、正常な動作を行いませんでした。

$json = new Jsphon_Decoder();$result = $json->decode($json_data);

おかしいなー?と思い原因を調査したところ、どうも JSON の値の要素を取得する際の preg_match(正規表現によるマッチング関数)で落ちている模様。

case $c == '"' and preg_match('/^"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"/', $src, $m):

(Jsphon/Decoder/Tokenizer.php 91行目)

preg_match の調査を行ったところ、16000バイト以上の検索結果が返ってくる場合に Segmentation Fault が発生する事が分かりました。
データ変更が目的では無い為、データ自体は弄ることは出来ません。
ですので、preg_match を問題が無かった mb_ereg に変更。

case $c == '"' and mb_ereg('^"([^"\\\\]*(?:\\\\.[^"\\\\]*)*)"', $src, $m):

また、mb_ereg を使う場合は、
コンストラクタ等で、mb_regex_encoding を使用し、正規表現用のエンコード設定をします。

mb_regex_encoding('UTF-8');

上記の対応を行う事で、正常な動作を行うことが出来ました。
PHP のこのような不具合をはじめて知ったので、報告と修正方法を兼ねてお話しました。
またこのようなあまり情報が無い不具合に遭遇した際には、ご紹介します。
Twitterこの記事を Retweet する
Twitterフェンリルのオフィシャルアカウントをフォローする

Copyright © 2019 Fenrir Inc. All rights reserved.