Skip to content

[テーマ管理] テーマ名に半角カッコを含むテーマがあると画面がエラーになる問題を修正しました - #2486

Merged
masaton0216 merged 3 commits into
masterfrom
fix/theme-ini-syntax-error
Aug 18, 2026
Merged

[テーマ管理] テーマ名に半角カッコを含むテーマがあると画面がエラーになる問題を修正しました#2486
masaton0216 merged 3 commits into
masterfrom
fix/theme-ini-syntax-error

Conversation

@masaton0216

Copy link
Copy Markdown
Contributor

概要

テーマ名に半角カッコ ( ) を含むテーマが存在すると、ページ管理の初期表示がシステムエラーになる不具合を修正しました。

原因

public/themes/**/themes.initheme_name に半角カッコがダブルクォートなしで書かれていると、parse_ini_file()syntax error, unexpected '(' の警告を出して false を返します。Connect-CMS は PluginBase::__construct()set_error_handler(ccErrorHandler) を設定しており、警告を ErrorException に変換して throw するため、壊れた themes.ini が1つあるだけで画面全体がシステムエラーになっていました。

作り込みの元はテーマ管理側で、theme_name を素のまま themes.ini に書き出していたことです(バリデーションも required のみ)。そのため、テーマ管理の画面から半角カッコ入りのテーマ名を登録すると、その直後から復旧できなくなる状態でした。

影響範囲はIssue記載のページ管理だけではなく、PluginBase::getThemes() を使う以下の画面すべてです。

  • ページ管理(一覧・ページ編集)
  • サイト管理
  • テーマ管理
  • テーマチェンジャープラグイン(公開画面
  • サイト設定書(PDF)出力

変更内容

Issueに記載いただいた恒久対策案1・2の両方を実施しました。既存サイトには既に壊れた themes.ini が存在しうるため、片方だけでは不十分と判断しています。

1. 読み込み側の堅牢化(対策案2)

App\Utilities\File\FileUtilsparseIniFile() を追加し、themes.ini を読む5箇所を置き換えました。

  • parse_ini_file()INI_SCANNER_RAW を指定し、ダブルクォートなしの ini 予約文字も読めるようにしています
  • それでも読めない壊れ方(例: セクション行が閉じていない)に備えて try/catch と is_array() チェックを行い、失敗時は空配列を返してログに warning を出します
  • あわせて getThemes() で、グループ用 themes.initheme_name が無い場合に未定義キー参照となっていた箇所も修正しました

置き換え箇所

  • PluginBase::getThemes()(第1階層・グループ配下の2箇所)
  • ThemeManage::index() / ThemeManage::getUserThemeName()
  • SiteManage(サイト設定書PDF出力)

なお ThemeManage::index()SiteManage はファイル存在チェックが無かったため、themes.ini の無いディレクトリがあるだけでもエラーになる状態でしたが、こちらも同時に解消されます。

2. 書き出し側の対応(対策案1)

  • テーマ管理の themes.ini 書き出し3箇所(テーマ作成・名称変更・カスタムテーマ生成)を makeThemesIni() に共通化し、theme_name を必ずダブルクォートで囲むようにしました
  • 同3箇所の theme_name のバリデーションに not_regex を追加し、ini の値として表現できない "\ を弾くようにしました(半角カッコは正しく扱えるため許可しています)

3. テスト追加

  • tests/Unit/Utilities/File/FileUtilsTest.php: escapeIniValue() のテストを追加
  • tests/Unit/Utilities/File/FileUtilsParseIniFileTest.php(新規): 既存フォーマットの後方互換7パターン、ini予約文字、ダブルクォート付き、書き出し→読み込みの往復、壊れたファイル、存在しないパス
  • tests/Unit/Plugins/PluginBaseGetThemesTest.php(新規): 半角カッコ入り themes.ini があっても getThemes() が例外を投げないこと

既存 themes.ini への影響(後方互換)

INI_SCANNER_RAW の指定で既存の読み込み結果が変わらないことを、PHP実機で確認しています。

themes.ini の値(ダブルクォートなし) 現行 変更後
theme_name = Blue Blue Blue(同一)
theme_name = カスタムテーマ1 同左 同左(同一)
theme_name = Users グループ + theme_dir = group 同左 同左(同一)
theme_name = clear-steelblue_01.2 同左 同左(同一)
theme_name = Blue (前後空白) Blue Blue(同一)
; コメント行あり 同左 同左(同一)
theme_name = theme_user_02 (clear-steelblue) エラーで画面が落ちる theme_user_02 (clear-steelblue)(本件の修正)

結果が変わるのは theme_nameon / true / null / PHP定義済み定数と完全一致する場合のみで、現行が値を 1 や空文字に変換してしまっていたものが、正しい文字列として読めるようになる方向の差異です。「今まで読めていたものが読めなくなる」パターンはありません。

既存の壊れた themes.iniINI_SCANNER_RAW によってそのまま正しく読めるようになるため、修復用のバッチやマイグレーションは不要です。テーマ管理の「名称変更」から保存し直せば、ダブルクォート付きに書き直されます。

確認内容

  • ユニットテスト
    • tests/Unit/Utilities/File/: OK (28 tests, 28 assertions)
    • tests/Unit/Plugins/PluginBaseGetThemesTest.php: OK (3 tests, 7 assertions)
  • phpcs(PSR-12): 指摘なし
  • 手動テスト
    • テーマ管理の画面から半角カッコ入りのテーマ名でテーマを登録 → themes.ini がダブルクォート付きで保存され、ページ管理・ページ編集・サイト管理・テーマ管理・テーマチェンジャー(公開画面)・サイト設定書PDF がいずれもエラーにならないこと
    • 名称変更・カスタムテーマ生成でも同様にダブルクォート付きで保存されること
    • "\ を含むテーマ名がバリデーションで弾かれ、ファイルが書き換わらないこと
    • 既存テーマ(Defaults 配下28件、ユーザ・テーマ)の表示名が従来通りであること、テーマの適用表示が従来通りであること
    • ダブルクォートなしの themes.ini を手置きした場合も、エラーにならずテーマ名が正しく表示されること
    • 復旧できないほど壊れた themes.ini があっても画面が落ちず、ディレクトリ名にフォールバックしてログに warning が出ること

レビュー完了希望日

不具合対応ですが、暫定対処(該当 themes.ini をダブルクォートで囲む)があるため、急ぎではありません。

関連Pull requests/Issues

参考

  • PHP: parse_ini_file — ini の予約文字と INI_SCANNER_RAW について

DB変更の有無

無し

チェックリスト

@masaton0216 masaton0216 added the bug バグ・不具合連絡 label Aug 18, 2026
@masaton0216 masaton0216 self-assigned this Aug 18, 2026
create() / saveName() / generate() の3箇所に同じルールとメッセージを
コピペしていたため、themes.ini に書き出せない文字の定義を
THEME_NAME_NG_REGEX / THEME_NAME_NG_MESSAGE の定数と
getThemeNameRules() に集約し、makeThemesIni() の近くに配置した。

refs #2465
テーマ設定ファイルにテーマ名がない場合のフォールバックを ?? で
書いていたが、これは getThemeName() が持つロジックの再実装だったため、
getThemeName() の戻り値に themes を足す形に変更した。
テーマ名の決定ルールが getThemeName() の1箇所に集約される。

refs #2465
@masaton0216
masaton0216 merged commit a55744e into master Aug 18, 2026
1 check passed
@masaton0216
masaton0216 deleted the fix/theme-ini-syntax-error branch August 18, 2026 08:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug バグ・不具合連絡

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant