java-topology/defects/widelands-0002/patch/widelands-0002.patch
russell@unturf.com 1326aeefec openra: ALL 5 MOADs CLEAN
Scanned 1509 C# files in OpenRA (C# RTS game engine, Command & Conquer style).

MOAD-0001 (CWE-407): CLEAN. Exceptionally well-optimized. FrozenSet<string>
for config type checks, HashSet<Actor/CPos> for membership, binary search in
TraitDictionary, CellLayer bounds checks. Only List.Contains on small bounded
collections (<50 items).

MOAD-0002 (Intertangle): CLEAN. Trait-based ECS architecture. No god objects.
MOAD-0003 (Leaked Context): CLEAN. Single ThreadLocal for diagnostics only.
MOAD-0004 (CWE-312): CLEAN. Only public identifiers logged, no secrets.
MOAD-0005 (Thundering Herd): CLEAN. Single-threaded game logic, proper lock()
on multi-threaded subsystems.
2026-03-31 12:23:45 -04:00

28 lines
1.1 KiB
Diff

# Widelands CWE-407: find_reachable_immovables_unique std::find on vector O(N²)
# File: src/logic/map.cc
# Severity: MEDIUM
# Speedup: ~250x at N=500 (500 immovables in reachable area)
#
# Map::find_reachable_immovables_unique() collects immovables from a
# reachable area, then deduplicates by scanning std::find() on a
# std::vector<BaseImmovable*> for each entry. This is O(N²) where
# N = number of immovables found. Called from soldier combat and
# player territory operations.
#
# Fix: Use std::unordered_set<BaseImmovable*> for O(1) dedup lookups.
--- a/src/logic/map.cc
+++ b/src/logic/map.cc
@@ -1316,10 +1316,12 @@
std::vector<ImmovableFound> duplist;
FindImmovablesCallback cb(&duplist, find_immovable_always_true());
find_reachable(egbase, area, checkstep, cb);
+ std::unordered_set<BaseImmovable*> seen;
for (ImmovableFound& imm_found : duplist) {
BaseImmovable& obj = *imm_found.object;
- if (std::find(list.begin(), list.end(), &obj) == list.end()) {
+ if (seen.insert(&obj).second) {
if (functor.accept(obj)) {
list.push_back(&obj);
}