From e868d02edd4991b9a74891fe2ce67fad953f7bbd Mon Sep 17 00:00:00 2001 From: Kelly Kinkade Date: Sat, 1 Aug 2026 21:48:48 -0500 Subject: [PATCH] add a safety check to `manageUnitAttackEvent` to avoid a potential crash based on a bug report in which DFHack crashed due to getting an erroneous result from `binsearch`, presumably due to crud in the DF vector --- docs/changelog.txt | 1 + library/modules/EventManager.cpp | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/docs/changelog.txt b/docs/changelog.txt index 300ae435f2..92f023062f 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -62,6 +62,7 @@ Template for new versions: - `buildingplan`: restore planner UI elements: hollow constructions, only engraved slabs, only empty cages, weapon count ## Misc Improvements +- `EventManager`: add safety check to potentially avoid a DFHack crash when DF's ``reports`` table is out of order ## Documentation diff --git a/library/modules/EventManager.cpp b/library/modules/EventManager.cpp index 3c926645a2..12aa4e7ed5 100644 --- a/library/modules/EventManager.cpp +++ b/library/modules/EventManager.cpp @@ -1136,6 +1136,11 @@ static void manageUnitAttackEvent(color_ostream& out) { multimap copy(handlers[EventType::UNIT_ATTACK].begin(), handlers[EventType::UNIT_ATTACK].end()); std::vector& reports = df::global::world->status.reports; size_t idx = df::report::binsearch_index(reports, lastReportUnitAttack, false); + if (idx >= reports.size()) + { + WARN(log, out).print("manageUnitAttackEvent: last reported unit attack lookup failed ({} -> {})\n", lastReportUnitAttack, idx); + return; + } // returns the index to the key equal to or greater than the key provided idx = reports[idx]->id == lastReportUnitAttack ? idx + 1 : idx; // we need the index after (where the new stuff is)