Ruby バージョンチェックへ移行し Bug #22023 検知ロジックを簡素化

rails/bootsnap

Bootsnap は Bug #22023 の有無判定に用いていた canary ファイルの実体評価を廃止し、Ruby のバージョン文字列だけで判定できるよう変更しました。これにより起動時のファイルロードが減り、判定ロジックが決定的かつ軽量になります。

背景

Bug #22023 は Ruby パーサが特定パターンを誤処理する問題で、過去は ruby_bug_22023_canary.rb をコンパイルさせ SyntaxError が発生するかで検出していました。canary 手法は Ruby のビルドやパッチレベルに依存し、同一バージョンでも結果が不安定になるケースが報告されていました。Ruby 4.0.4 で同バグは修正され、3.4 系でも 3.4.10 にバックポートされることが確定したため、バージョン範囲での判定が実現可能となりました。

技術的な変更

判定ロジックの置き換え

has_ruby_bug_22023 は now canary のコンパイルから RUBY_VERSION の正規表現マッチへ 置き換えられました。case RUBY_VERSION 文で対象バージョンを列挙し、該当する場合は true、それ以外は false を返すシンプルな実装です。

変更前:

has_ruby_bug_22023 = if defined?(RubyVM::InstructionSequence) && RubyVM::InstructionSequence.respond_to?(:compile_file_prism)
  begin
    RubyVM::InstructionSequence.compile_file(File.expand_path("../ruby_bug_22023_canary.rb", __FILE__))
    false
  rescue SyntaxError
    true
  end
end

変更後:

has_ruby_bug_22023 = case RUBY_VERSION
when /^3\.3\./
  true
when /^3\.4\.(\d+)/
  $1.to_i < 10
when /^4\.0\.(\d+)/
  $1.to_i < 4
else
  false
end

canary ファイルの内容変更

ruby_bug_22023_canary.rb はファイル自体は残りますが、実装コードがすべて削除され _ = "test" のみが残っています。これによりコンパイル時にバグを誘発する構文はなくなり、実行時の副作用がなくなります。

RuboCop 設定の追加

.rubocop.yml に以下の設定が追記され、削除された canary の残骸が RuboCop の対象外になるよう調整しました。

Layout/CaseIndentation:
  EnforcedStyle: end

Style/PerlBackrefs:
  Enabled: false

設計判断

バージョンチェックへの一本化 が本変更の中心的な設計判断です。Ruby のバージョンはビルド時に確定しており、外部ファイルの評価に依存しないことで判定の再現性が向上しました。トレードオフとしては、将来的に同様のバグが新バージョンで再び発生した場合に case 文を更新する必要がありますが、ロジックは単一の式に集約されているためメンテナンスコストは低く抑えられます。インターフェース名 has_ruby_bug_22023 は変更していないため、他コンポーネントへの破壊的影響はありません。

まとめ

Bootsnap は Bug #22023 の検出手段を canary 依存から Ruby バージョン判定へ置き換えることで、起動時オーバーヘッドを削減しつつ判定の確実性を高めました。canary ファイルは内容が削除され、RuboCop 設定も併せて整理されたため、コードベースの整合性が保たれています。

記事メタデータ

Generated by:
gpt-oss-120b for DiffDaily
LLM Trace:
4ee398ae

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
リトライ後承認
Review Count:
3回 (改善を経て承認)
Reviewed by:
gpt-oss-120b for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文・背景・技術的詳細・設計判断・まとめの5セクションが揃っており、総論→各論→結論の流れが明確です。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

コードブロックは `ruby:ファイルパス` 形式で正しく記載され、GitHubリンクも PR番号がリンク化されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

専門エンジニア向けの内容で、不要な基礎説明はなく適切な技術レベルです。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションは総論・各論・結論の段落構成で、トピックセンテンスで始まり、1段落1トピック・6文以内に収まっています。空行で区切りも適切です。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事中のコードブロックはDiffに示された変更と完全に一致し、ファイル名もDiffと合致しています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

用語(canary、RUBY_VERSION、RubyVM::InstructionSequence など)は PR と一致し、誤用はありません。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

技術的説明は Diff と PR の記述に根拠があり、因果関係も正しく示されています。

事実の突合 ✓ PASS

PR情報による主張の裏付け(ハルシネーション検出)

全ての主張は PR タイトル・説明・Diff で裏付けられ、根拠のない推測や外部知識は含まれていません。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR 番号 #556、Ruby バージョン番号、コード内の数値比較など、数値・固有名詞は正確です。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事タイトルは PR タイトルの意味合い(Bug #22023 を canary から Ruby バージョンで判定)を日本語で正確に表現しています。

外部知識の正確性 ✓ PASS

PRに記載のない外部知識(LTS、サポート状況など)の不使用

LTS やリリーススケジュール等の外部情報は記載せず、PR に記載された内容だけに留めています。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

「修正された」「バックポートされる」等の時間表現は PR の記述と一致しており、歪曲はありません。