Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Garoon開発チームではPHP8.1の仕様変更とどう向き合ってきたのか / How we have responded to the PHP 8.1 mbstring specification changes

Garoon開発チームではPHP8.1の仕様変更とどう向き合ってきたのか / How we have responded to the PHP 8.1 mbstring specification changes

【Cybozu Tech Meetup #21】PHPerKaigi 2023 後日談 発表スライド
https://cybozu.connpass.com/event/277790/

Chiba Tairi

April 05, 2023
Tweet

More Decks by Chiba Tairi

Other Decks in Programming

Transcript

  1. 0
    #Garoon 開発 #完成度低いの歓迎LT大会
    Garoon開発チームでは
    PHP 8.1の仕様変更と
    どう向き合ってきたのか
    〜 mb_detect_encodingを例に 〜
    サイボウズ Garoon開発チーム 千葉 泰理(ぱくとま)

    View full-size slide

  2. 1
    #Garoon 開発 #完成度低いの歓迎LT大会 1
    - タイトルを変えました
    - PHPerKaigiで話したいことは話した
    - 社内イベントなので、もうすこし社内っぽいことを話したい
    - とは言っても、結局mbstringのことを話します
    - ぱくとま(千葉 泰理)
    - 4月でサイボウズ2年目になりました
    - Yukimiチームに所属
    - GaroonのPHPやライブラリのアップデート対応
    おことわり & 自己紹介

    View full-size slide

  3. 2
    #Garoon 開発 #完成度低いの歓迎LT大会 2
    - バイト列の文字エンコーディングを「検出」する関数
    - 実際には、最も可能性が高いエンコーディングを「推測」
    - エンコーディングの候補を配列で渡す
    - 日本語なら[ASCII, UTF-8, JIS, EUC-JP, SJIS-win]とか
    - 一番もっともらしいものを選ぶ(ということになっている)
    - PHP 8.0までは、最初に出現したvalidな候補を返す
    mb_detect_encoding() とは?

    View full-size slide

  4. 3
    #Garoon 開発 #完成度低いの歓迎LT大会 3
    - 主にメールの受信に利用されていた
    - メールのヘッダーと本文のエンコーディングを推測
    - MIMEヘッダーのcharset指定は無視されていた
    - 本文から推測した方が成功率が高いという判断らしい
    - 経緯は不明、過去の規格違反メールへの対策?
    Garoon での使われ方

    View full-size slide

  5. 4
    #Garoon 開発 #完成度低いの歓迎LT大会 4
    - PHP 8.1でmb_detect_encoding()の仕様が変更
    - エンコーディングの配列を渡したとき
    - PHP 8.0まで
    - 正常にエンコードされた最初のエンコーディングを返す
    - PHP 8.1から
    - 一番それらしいエンコーディングを返す
    mb_detect_encoding()のサイレント仕様変更

    View full-size slide

  6. 5
    #Garoon 開発 #完成度低いの歓迎LT大会 5
    - 一番それらしいエンコーディング……?
    - 文字列に対してスコアリングする
    - 常用漢字外の漢字や、U+FFFF以上の文字(絵文字など)は
    低いスコアが付く
    - 出現頻度が低い文字で誤検出が発生
    - 例えば、🍣(寿司)をUTF-8ではなくSJIS-winとして認識
    - Garoonでは、名字の異体字が文字化けした
    mb_detect_encoding()の検出方法

    View full-size slide

  7. 6
    #Garoon 開発 #完成度低いの歓迎LT大会 6
    - PHP 8.0の挙動を再現したラッパー関数を作成
    - どうやって再現する?
    - mb_check_encodingで代用すれば良いと思っていた
    - Alex Dowad氏もそう言っていたし……。
    - mb_check_encodingに様々な問題が発覚した
    mb_detect_encoding() のラッパー関数

    View full-size slide

  8. 7
    #Garoon 開発 #完成度低いの歓迎LT大会 7
    - ASCIIかどうかの判定基準の違い
    - PHP 8.0のmb_detect_encoding
    - 0x20-0x80とCR, LF, HTAB, NULのみを許容
    - mb_check_encoding
    - 0x00-0x7Fを全て正しいASCIIと判定
    - JISをASCIIと誤認識
    - mb_check_encodingの仕様としては正しい
    mb_check_encoding()の問題 その1

    View full-size slide

  9. 8
    #Garoon 開発 #完成度低いの歓迎LT大会 8
    - JISかどうかの判定基準の違い
    - PHP 8.0のmb_check_encoding:
    - 7bit文字+エスケープシーケンスのみをJISとして判定
    - PHP 8.1のmb_check_encoding:
    - 8bitの半角カナなどをJISとして判定
    - エスケープシーケンスが欠落していてもJISとして判定
    - EUC-JPや壊れたJISをJISとして誤認識
    mb_check_encoding()の挙動 その2

    View full-size slide

  10. 9
    #Garoon 開発 #完成度低いの歓迎LT大会 9
    - JISをASCIIと誤認識する
    - 以前の挙動を再現した関数を用意して対応
    - EUC-JPなどをJISと誤認識する
    - PHPに独自パッチを当てて対応
    - PHP側に聞いてみたが、正常動作とのこと
    - エスケープシーケンスが欠落したJISを誤認識する
    - PHP側にissue登録→修正
    ラッパー関数を作成する際の対応

    View full-size slide

  11. 10
    #Garoon 開発 #完成度低いの歓迎LT大会 10
    - エスケープシーケンスが欠落したJISを誤認識する件
    - JISとISO-2022-JPは改修された🎉(おまけでUTF-7も)
    - ISO-2022-JPの変種(-2004など)の対応はまだ
    - PR書きたいんですが、ちょっとお休み中です
    - 8bit 半角カナがJISとして判定される件
    - 社内ではパッチを当てているものの、今後どうするかは検討中
    - PHP側の実装を使えるのが理想
    PHP側への働きかけ

    View full-size slide

  12. 11
    #Garoon 開発 #完成度低いの歓迎LT大会 11
    - ひとまず修正リリースは出来たが、良い状態ではない
    - 複雑怪奇な動作をするラッパー関数
    - PHP本体に取り込まれなかった独自パッチ
    - メール機能の文字コード周りをほとんど作り直す
    - MIMEヘッダーを出来るだけ利用
    - mb_detect_encodingの利用は必要最低限に
    - 規格違反メールの文字化けはある程度許容したい
    - 改修に向けて作業中
    根本解決への道筋

    View full-size slide

  13. 12
    #Garoon 開発 #完成度低いの歓迎LT大会 12
    - 仕様変更は、コード品質の低い部分ほど影響が大きい
    - 必然的に厳しいコードを目にする機会が増える
    - プロダクトの光と闇だと、闇を目にするほうが圧倒的に多い
    - プロダクトの中で一番問題がある部分を改善していける
    - PHPアップデートの度に Garoon は進化しています
    - 仕様変更はプロダクトの弱い部分を成長させる機会
    レガシーコードとの戦い

    View full-size slide

  14. 13
    #Garoon 開発 #完成度低いの歓迎LT大会 13
    - 完成度低いポイント:Garoonのメール & mbstring
    - つらい
    - 見つけたものは改善出来る、だから良いこと!
    - GaroonでもOSSでも一緒ですね
    - 社内外のレガシーコードに立ち向かっています
    - ありがとうございました!
    まとめ

    View full-size slide