操作
バグ #475
完了バグ #474: コードベース健全性: メモリリーク・重大バグの一括調査と修正
選曲ソートのクラッシュ修正(Comparator contract 違反 / sortid 未検証)
バグ #475:
選曲ソートのクラッシュ修正(Comparator contract 違反 / sortid 未検証)
説明
現象¶
選曲画面のソートで 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:381のSort.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:381のsorter != 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 にフォールバックしクラッシュしない。
操作