All projects with patches now have outreach docs. 276 new docs covering CWE-407, CWE-312, CWE-362 across C, C++, Java, Python, Go, Rust, C#, PHP, Ruby, JavaScript, Dart, Erlang, R, and more. Outreach gap: 276 -> 0.
2.7 KiB
OpenXcom — CWE-407 Disclosure Brief (openxcom-0001)
2026-04-13 · Patch available — awaiting upstream merge
Finding
O(N²) membership tests in AIModule where std::find scans _reachable and _reachableWithAttack vectors (both vector<int>) for every tile evaluated during AI decision-making. Fires per alien unit per AI turn.
The Defect
openxcom-0001 (PATCHED — HIGH): src/Battlescape/AIModule.cpp
std::vector<int> _reachable, _reachableWithAttack;
// Called multiple times per AI evaluation — O(T) per call:
if (std::find(_reachable.begin(), _reachable.end(),
_save->getTileIndex(checkPath)) == _reachable.end())
...
if (std::find(_reachableWithAttack.begin(), _reachableWithAttack.end(),
_save->getTileIndex(pos)) == _reachableWithAttack.end())
...
Multiple call sites throughout AI evaluation (lines 612, 902, 1165, 1462, 2096) scan these vectors. With T reachable tiles per unit and U units per AI turn, total cost is O(U × calls × T).
Complexity Proof
At T=2,000 reachable tiles per unit and 5 std::find call sites:
- Defective: 5 × 2,000 = 10,000 comparisons per unit per evaluation cycle
- Fixed: 5 hash lookups per unit
- ~2,000× op reduction per unit per evaluation cycle.
Impact
OpenXcom reimplements X-COM: UFO Defense. AI turns process every alien unit, each evaluating reachable tiles for movement and attack decisions. Large battlescape maps (Terror missions, base assaults) with 20+ alien units and thousands of reachable tiles per unit make AI turns visibly slow. The original game supported fewer simultaneous AI units, but OpenXcom mods expand enemy counts significantly.
The Fix
Replace vector<int> with unordered_set<int> for _reachable and _reachableWithAttack. Convert findReachable() results from vector to set at assignment:
std::unordered_set<int> _reachable, _reachableWithAttack;
// ...
std::vector<int> rv = _save->getPathfinding()->findReachable(...);
_reachable = std::unordered_set<int>(rv.begin(), rv.end());
// ...
_reachable.count(_save->getTileIndex(checkPath)) == 0 // O(1)
Patch
Fix available: defects/openxcom-0001/patch/openxcom-0001.patch
Two-file patch across AIModule.h and AIModule.cpp.
What We Ask
A patch is ready for review.
- Confirm receipt and assign a GitHub issue reference (OpenXcom/OpenXcom).
- Assess severity — fires per alien unit per AI turn, compounds with map size and unit count.
- Coordinate a disclosure date — we target 90 days from first contact.
- We will credit the OpenXcom team in the public disclosure. Preferred acknowledgment format welcome.
Contact: see cover email. This brief is confidential until coordinated disclosure.