Repository navigation
fix: Web SAPI の fatal error と read() のメモリ枯渇などを直す(v1.3.4) - #18
Conversation
FFI 無効の Windows では,警告を fwrite(STDERR, ...) で出していた. STDERR は CLI でのみ定義されるため,php -S・Apache・FPM などでは Windows クラスの生成時点で Error が投げられ,fatal error になっていた. STDERR があれば従来どおり書き出し,無ければ error_log() へ送る. 内蔵 Web サーバーの実プロセスで fixture を実行するテストを加えた. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
fread() と FFI::new("char[n]") は指定長のバッファを先に確保する.
長さに上限がなく,外部入力をそのまま渡すと memory_limit を超えて
fatal error になった.CVE-2026-109618 はこの種のメモリ不足処理が
引き金であり,未修正の PHP では攻撃の入口にもなりうる.
検証と丸めを ReadLength へ集め,Unix・Windows・WindowsFFI から使う.
read() は最大 n バイトを返す API のため,例外にせず上限へ丸める.
1 未満は従来どおり例外とし,WindowsFFI にも同じ検証を入れた.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
PCRE の $ は末尾の改行の手前でも一致するため,"COM1\n" や "/dev/ttyUSB0\n" が検証を通っていた.Windows 版はこの名前を cmd.exe の mode コマンドへそのまま渡す.後ろへ命令を足せないため 注入には至らないが,検証の意図と食い違う. 全プラットフォームの正規表現へ D 修飾子を付け,文字列の末尾でのみ 一致させる. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CreateFileA の戻り値と (HANDLE)-1 を === で比べていた.FFI\CData 同士の === はオブジェクトの同一性を比べるため常に偽となり,失敗を 見逃して無効なハンドルを返していた. == はポインタ値を比べるため,こちらで INVALID_HANDLE_VALUE を判定する. 存在しない COM255 を開くテストを Windows + FFI 環境向けに加えた. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
送信バッファを FFI::new(..., false) で確保していた.所有権を持たない 確保は FFI::free() を呼ぶまで解放されず,送信のたびにメモリが増えた. 常駐プロセスでは,やがて memory_limit に達する. WriteFile は同期呼び出しのため,所有権付きで確保して破棄と同時に 解放させる.無効なハンドルへの書き込みを繰り返し,メモリ増分を 測るテストを加えた(修正前は 8 回で約 8 MiB 増えていた). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
戻り値は常に 1 以上のため,PHPDoc で int<1, max> と宣言する. PHPStan が fread() の length 引数(int<1, max>)との不一致を報告していた. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
read() が 64 KiB へ丸めることと,1 未満で例外になることを書く. FFI 無効時の警告は,Web 系 SAPI ではエラーログへ出ることを書く. あわせて,セキュリティ修正が提供される PHP の利用を推奨する. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ReadLength は Platform 実装の内部部品のため @internal を付け,README からクラス名を外す.patch リリースで公開 API を増やさないためである. WebSapiTest は,CI ランナーの起動の遅さを見込んで待ち時間を 15 秒へ 延ばす.子プロセスが先に終了した場合はログを添えて即座に落とし, 一時ファイルは finally で必ず消す. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lint summary
検査対象: 差分行に該当する指摘は inline コメントとして該当行に付きます.filter-mode(既定 markdownlint の指摘 45 件
textlint の指摘 84 件
Actions run: https://github.com/tomio2480/php-serial/actions/runs/39623855448/attempts/1 |
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configuration
You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
全角文字と半角文字の間へ半角スペースを入れる. README.md と docs/WINDOWS_FFI_SETUP.md は利用者向けの手引きで, 本文全体が「ですます調」・句点「。」で書かれている.追記行だけを である調や「.」へ変えると 1 ファイル内で混ざるため,文体と句点の 2 ルールをファイル単位のコメントで無効化する.判断は CLAUDE.md に記す. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
@codex review |
reviewdog レビュー対応2e83ad9 で対応した.再実行後,追記行へのインライン指摘は 0 件である.
文体の判断はリポジトリの |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
|
Codex Review: Didn't find any major issues. Swish! Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
セルフレビュー実施済み(
self-reviewerによる一次走査と/security-reviewを実行).概要
2026-10-21 の PHP セキュリティアドバイザリ(CVE-2026-109618 / CVE-2026-109619)を受けて,ライブラリを再点検した.
PHP 本体の脆弱性はライブラリ側では直せない.一方,アドバイザリが挙げる緩和策に関わる弱点が見つかったため,5 件を直す.
v1.3.4 として出す想定である.
対応する Issue はない.
変更内容
Windows.php)FFI 無効の Windows では警告を
fwrite(STDERR, ...)で出していた.STDERR は CLI でのみ定義されるため,
php -S・Apache・FPM では Windows クラスの生成時点で fatal error になっていた.STDERR が無ければ
error_log()へ送る.アドバイザリの「攻撃者が到達できる fatal error を直す」に当たる.read()の長さを 64 KiB へ丸める(新設ReadLength,各プラットフォーム)fread()とFFI::new("char[n]")は指定長を先に確保する.上限がなく,巨大な指定で memory_limit を超えて fatal error になっていた.CVE-2026-109618 の引き金と同種のメモリ不足である.
read()は最大 n バイトを返す API のため,例外にせず上限へ丸める.PCRE の
$は末尾改行の手前でも一致し,"COM1\n"が通っていた.D修飾子を付ける.WindowsFFI::write()の送信バッファを解放するFFI::new(..., false)の確保を解放しておらず,送信のたびにメモリが増えていた.所有権付きの確保に変える.WindowsFFI::open()の失敗を判定するFFI\CData同士の===はオブジェクトの同一性を比べ,常に偽だった.ポインタ値を比べる==に変える.README と
docs/WINDOWS_FFI_SETUP.mdに,read()の上限と警告の出力先を追記した.ReadLengthは内部部品として@internalを付け,公開 API を増やさない.セルフレビューで見送った指摘
Windows.phpのパリティ検証/^[noe]$/にD修飾子がない.値は固定の対応表からしか来ず,改行は入りえないため見送った.fwriteがTypeErrorになりうる.利用者が自ら STDERR を閉じる稀な場合に限られ,今回の範囲外とした.互換性
read()に 64 KiB を超える長さを渡すと,返る最大長が 64 KiB になる.もともと「最大 n バイト」の API のため,patch リリースの範囲とした.RuntimeExceptionになる.従来も正しく動作しない入力である.テスト
各修正は Red を確認してから実装した(TDD).
tests/WebSapiTest.phpphp -n -Sの実プロセスで fixture を実行し,fatal にならず警告がログへ出ることを確かめるtests/ReadLengthTest.phpPHP_INT_MAX・PHP_INT_MIN)と,Unix / Windows の丸めtests/SecurityTest.phptests/WindowsFFITest.phpCOM255の open 失敗,無効ハンドルへの write 反復でメモリが増えないこと(Windows + FFI のみ)ローカル(Windows,PHP 8.5.12)で
composer test・cs:check・cs:fixer・stanが通過した.PHPUnit Deprecations: 1はphpunit.xmlのスキーマ警告で,本 PR 以前から出ている.ドキュメント整合性
README・
docs/WINDOWS_FFI_SETUP.mdを差分と照合し,必要な追記を本 PR に含めた..env.example・CONTRIBUTING.mdは変更不要と確認した.リリースノート案(v1.3.4)
マージ後,
v1.3.4タグの作成と GitHub Release の公開を行う(Packagist はタグで更新される).🤖 Generated with Claude Code