プロジェクト

全般

プロフィール

バグ #475

完了

バグ #474: コードベース健全性: メモリリーク・重大バグの一括調査と修正

選曲ソートのクラッシュ修正(Comparator contract 違反 / sortid 未検証)

バグ #475: 選曲ソートのクラッシュ修正(Comparator contract 違反 / sortid 未検証)

エージェント ちゃん さんが7日前に追加. 6日前に更新.

ステータス:
完了
優先度:
高め
担当者:
対象バージョン:
開始日:
2026/06/29
期日:
進捗率:

100%

予定工数:

説明

現象

選曲画面のソートで IllegalArgumentException: Comparison method violates its general contract! または IllegalArgumentException(不正 sortid)が発生しクラッシュする。

原因と対象

1. long 差分の int キャスト(推移律違反・確定)

  • src/bms/player/beatoraja/select/BarSorter.java:201(DURATION): (int)(o1.getScore().getAvgjudge() - o2.getScore().getAvgjudge())
  • src/bms/player/beatoraja/select/BarSorter.java:219(LASTUPDATE): (int)(o1.getScore().getDate() - o2.getScore().getDate())
  • getAvgjudge()/getDate()long。差が int 範囲(±2.1e9)を超えると符号反転し、libgdx TimSort(BarManager.java:381Sort.instance().sort)が contract 違反を検出して例外を投げる。曲数の多いフォルダで DURATION/LASTUPDATE ソートを選ぶと再現。

2. BarSorter.valueOf 未検証 + デッドコード

  • src/bms/player/beatoraja/select/BarManager.java:380: BarSorter.valueOf(getPlayerConfig().getSortid()) を未検証で呼ぶ。PlayerConfigValidator.java:86 は null のときだけ補完し、列挙名妥当性は検証しない。空文字/旧バージョン/手編集値で IllegalArgumentException
  • BarManager.java:381sorter != null ? sorter.sorter : BarSorter.TITLE.sorterデッドコード(valueOf は null を返さず例外を投げる)。

修正方針

  • DURATION/LASTUPDATE を Long.compare(...) に置換。
  • BarManager.java:380 を try/catch で囲んで TITLE にフォールバック(または PlayerConfigValidator で列挙名 whitelist 検証を追加)し、デッドコードの三項演算子を整理。
  • (予防)BPM/LENGTH/CLEAR/MISSCOUNT/RIVALCOMPARE 等の int 同士減算も Integer.compare/Float.compare 系に統一すると安全(現状は非負・小値域で実害低)。

検証

  • 多数曲フォルダで DURATION/LASTUPDATE ソートしてもクラッシュしない。
  • 不正 sortid の config で起動 → TITLE にフォールバックしクラッシュしない。

他の形式にエクスポート: PDF Atom