Hostage pathfinding CLocalNav::FindPath() calls NodeExists() inside BFS
expansion loop. NodeExists() linearly scans all existing nodes to check
if coordinate pair already exists. With MAX_NODES=100, this is O(N^2)
per FindPath() call (8 AddPathNode calls per expansion, each scanning
all N nodes).
Fix: unordered_set keyed on packed (offsetX, offsetY) for O(1) lookup.
Reduces FindPath() from O(N^2) to O(N). 31.1x op-count reduction at
N=100, 4/4 PASS.
MOAD-0002 (intertangle): gpGlobals is standard GoldSrc engine state, CLEAN.
MOAD-0003 (leaked context): single-threaded game DLL, no thread_local, CLEAN.
MOAD-0004 (logged secret): no RCON/auth handling in game DLL, CLEAN.
MOAD-0005 (thundering herd): single-threaded, no concurrent cache, CLEAN.
Space flight simulator with clean data structure discipline.
No CWE-407 on hot paths. Docking uses one-vessel-per-frame
amortized scan. MOAD-0002 present (47+ files coupled through
global mutable state) but architectural, not patchable.
regamedll-0001: BotProfileManager::GetRandomProfile calls UTIL_IsNameTaken
O(C) per profile in loop over all profiles O(P), yielding O(P*C*2) string
comparisons. Fix: build taken-name set once O(C), check O(1) per profile.
19.8x at P=100/C=32, 4/4 PASS.
simutrans-0001: rebuild_linked_connections() append_unique O(C*H^2) MEDIUM 97x
- vector_tpl::append_unique linear scan inside double loop over
goods categories x connections to collect unique connected halts
- fix: inthashtable_tpl for O(1) membership test
simutrans-0002: add_grund() registered_convoys.is_contained O(C*R) MEDIUM 45x
- iterates ALL world convoys, each with linear scan of registered
convoy vector to check membership
- fix: pre-build hash set of registered convoy IDs for O(1) lookup
simutrans-0003: rebuild_connections() consecutive_halts append_unique O(S^2) MEDIUM 24x
- append_unique on consecutive halt vectors per category inside
nested loop over schedules x entries during halt reconnection
- fix: parallel inthashtable_tpl for O(1) dedup
All three defects are in simhalt.cc halt reconnection paths, triggered
whenever schedules change (line added/removed, schedule edited, station
built). In large games with hundreds of halts and convoys, these
compound during reconnection sweeps.
MOAD-0002: welt (karte_t) is a god object but standard Simutrans architecture
MOAD-0003: CLEAN (no thread_local usage)
MOAD-0004: CLEAN (nettool password printf is by-design tool output)
MOAD-0005: CLEAN (save cache uses hashtable, no unsynchronized pattern)
bzflag-0001: bz_EventHandler::HasEvent() std::find on HandledEvents vector
called per-handler per-event-fire in callEvents hot path. O(E*H).
Fix: std::bitset<bz_eLastEvent>. HIGH, 8.4x speedup.
bzflag-0002: AccessControlList ban/hostBan/idBan std::find on growing
ban vector for dedup. O(B^2) during merge() of master ban list.
Fix: parallel unordered_set index. MEDIUM, 17x speedup.
bzflag-0003: parsePermissionString customPerms std::find dedup O(W*C).
Fix: std::set shadow for dedup. LOW-MEDIUM, 5.1x speedup.
MOAD-0004: bzfs.cxx:4732 logs auth token verbatim at debug level 1
(logDebugMessage with player token). Noted, not patched (debug only).
MOAD-0002 (intertangle): global mutable state typical for 1993 C++ game
server, not a clean god-object coupling defect.
MOAD-0003 (leaked context): no thread_local usage found. CLEAN.
MOAD-0005 (thundering herd): single-threaded server, no cache races. CLEAN.
naev-0001: map.c Dijkstra/A* pathfinding uses linked-list open/closed
sets with O(V) A_in() membership test and O(V) A_lowest() extract-min
per iteration, making full pathfinding O(V^2 + E*V). Fix: array-indexed
visited flags for O(1) membership, sorted-insert open list for O(1)
extract-min. 102.5x at V=500 (Naev has 538 star systems). HIGH.
naev-0002: tech.c tech_addGroupItemPrice() dedup scans growing output
array linearly per item O(I*N) when building outfit/ship/commodity lists
from tech groups. Fix: hash set for O(1) amortized dedup. 333x at
N=1000. MEDIUM.
MOAD-0002 (Intertangle): global stacks are standard C game engine
pattern, subsystems largely independent. CLEAN.
MOAD-0003 (Leaked Context): single thread_local in Rust RNG only. CLEAN.
MOAD-0004 (Logged Secret): no credentials in single-player game. CLEAN.
MOAD-0005 (Thundering Herd): single-threaded gameplay logic. CLEAN.
2/2 PASS, 2 defects.
236 source files scanned. Property tree uses O(N) find_child but only in
config-phase code. Runtime property access uses cached direct pointers.
Single-threaded codebase with small fixed-size collections throughout.
openxcom-0001: AIModule _reachable/_reachableWithAttack std::vector<int>
with std::find() inside AI loops (setupAmbush, setupEscape,
selectPointNearTarget, findFirePoint). O(N*R) per alien turn where
N = nodes checked, R = reachable tiles (~500 on typical map).
Fix: std::unordered_set<int> for O(1) lookup. MEDIUM-HIGH, 7.6x.
openxcom-0002: SavedGame::isResearched linear scan of _discovered vector
O(D) per call, called O(R*4) times from getAvailableResearchProjects
per base. Also unlocked vector with std::find O(R*U).
Fix: parallel unordered_set<string> for O(1) lookup. MEDIUM, 4.5x.
MOAD-0002 (Intertangle): CLEAN, typical game state architecture
MOAD-0003 (Leaked Context): CLEAN, single-threaded game
MOAD-0004 (Logged Secret): CLEAN, no credentials
MOAD-0005 (Thundering Herd): CLEAN, no concurrent caching
pioneer-0001: Sensors::Update m_radarContacts linear scan O(N*C) per frame
MEDIUM-HIGH, 250x at N=C=500. Hash set for O(1) membership check.
pioneer-0002: Faction::IsClaimed m_ownedsystemlist linear scan O(S*F*C)
MEDIUM, 219x at C=500. std::set for O(log C) lookup during sector gen.
pioneer-0003: SectorView::GetDisplayMode m_route std::find_if O(S*R) per frame
MEDIUM, 50x at S=5000 R=50. Hash set for O(1) route membership.
MOAD-0002 (Intertangle): Pi class is god object but architectural, not patchable.
MOAD-0003 (Leaked Context): CLEAN, thread_local used only for task graph internals.
MOAD-0004 (Logged Secret): CLEAN, no credentials in codebase (space sim).
MOAD-0005 (Thundering Herd): CLEAN, GalaxyCache uses map with proper locking.
3/3 unit tests PASS.
spring-rts-0001: CWeapon::HasIncomingProjectile std::find on vector O(I)
called from InterceptHandler::Update() O(W*P) nested loop = O(W*P*I).
Fix: std::unordered_set<int> for O(1) lookup. 3x measured at W=10 P=200 I=100.
spring-rts-0002: GameServer logs passwords verbatim (CWE-312).
Two LOG() calls in adduser command handler emit pwd.c_str() to log output.
Fix: remove password values from log format strings.
MOAD-0002 (intertangle): pervasive global state (gs, gu, handlers) but
architectural, not patchable per-defect.
MOAD-0003 (leaked context): thread_local in Threading.cpp is infrastructure,
not request-scoped identity. CLEAN.
MOAD-0004: spring-rts-0002 covers this.
MOAD-0005 (thundering herd): simulation is single-threaded for determinism.
No unsynchronized cache patterns. CLEAN.
Defect: ByGivenOrder<T> uses std::find() on a vector for every comparison,
making it O(N) per call. Used as std::map comparator in MainPanel.cpp for
outfit scanning, giving O(O * C * log C) total scan operations where C is
category count and O is outfit count.
Fix: replace vector + std::find with unordered_map<T, size_t> for O(1)
index lookup per comparison. 338x fewer scan operations measured at
C=500 O=1000. Correctness verified: sort order and map iteration order
match original for known values, unknown values, and mixed inputs.
MOAD-0002: GameData has 80 static members (god object), typical for
single-threaded game architecture. Not a fixable defect.
MOAD-0003: CLEAN. thread_local used appropriately for Random/Files/CollisionSet.
MOAD-0004: CLEAN. No credentials or secrets in a space trading game.
MOAD-0005: CLEAN. Single-threaded game, no concurrent cache access.
BFS flood fill in server/generator/mapgen_utils.c uses tile_list_search()
(O(N) linked-list scan) as visited check per adjacent tile. On a continent
of T tiles, each tile's 4-8 neighbors each trigger a linear scan of our
growing worklist, making total complexity O(T * adj * T) = O(T^2).
Fix: set tile_continent() at enqueue time instead of dequeue time. Our
continent field itself becomes our visited set, replacing O(N) membership
checks with O(1) integer comparisons. Worklist is now a pure FIFO queue.
Measured: 53x overhead at T=25,600 tiles (160x160 map).
Standard large Freeciv maps have continents of 5,000-20,000+ tiles.
MOAD 0002 (Intertangle): Freeciv uses struct civ_game as global god object,
expected for a single-threaded C game from 1996. Not a practical defect.
MOAD 0003 (Leaked Context): CLEAN. Thread-local only in bundled tinycthread
dependency. Tex AI uses proper mutexes.
MOAD 0004 (Logged Secret): CLEAN. auth.c logs rejection messages with
usernames only, never passwords or credentials.
MOAD 0005 (Thundering Herd): CLEAN. AI settler cache uses hash lookup,
single-threaded game loop has no concurrent cache races.
Note: patches and tests committed in 1326aee (bundled with openra by parallel agent).
MOAD-0001 (CWE-407):
- widelands-0001: FindBobsCallback std::find dedup O(B^2) in map.cc, HIGH, 21.5x
36 callers: combat soldier finding, critter AI, ship fleet, worker tasks
- widelands-0002: find_reachable_immovables_unique std::find dedup O(N^2) in map.cc, MEDIUM, 28.7x
Called from soldier combat and player territory operations
- widelands-0003: cleanup_playerimmovables_area burnlist std::find O(N^2), MEDIUM, 29.6x
Called during territory changes (conquest, diplomacy)
All 3/3 unit tests PASS.
MOAD-0002: Global singletons (g_fh, g_sh, g_image_cache, g_gr) typical for game engine. CLEAN.
MOAD-0003: Single thread_local in rt_parse.cc, not request-scoped. CLEAN.
MOAD-0004: Passwords handled via SHA1 hash, never logged verbatim. CLEAN.
MOAD-0005: Mutex usage in network/sound. No unsynchronized cache patterns. CLEAN.
Defect: projectile.cpp line 872, std::find on std::vector<BASE_OBJECT*>
psDamaged inside grid neighbor iteration loop. Every projectile tick,
for each nearby object, does O(D) linear scan to check if already
damaged. Penetrating weapons inherit and grow psDamaged across hits.
Fix: replace std::vector with std::unordered_set for O(1) lookup.
push_back becomes insert, std::find becomes count, remove_if becomes
iterator-based erase loop.
Severity: MEDIUM. Hot path (per projectile per tick), scales with
battle density. D=200 damaged, G=100 grid neighbors: 9.5x speedup.
MOAD 0002-0005 CLEAN:
- 0002: global state is architectural (Eidos-era C game), not coupling defect
- 0003: no thread_local usage found
- 0004: no secrets logged (public keys and IPs only, standard for server logs)
- 0005: no unsynchronized cache patterns (game logic is single-threaded)
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.
wesnoth-0001: A* pathfinding std::find on pq vector for decrease-key
O(V*Q) per relaxation, fix: lazy deletion. HIGH, 1279x at N=5000.
wesnoth-0002: server ip_log_ deque linear scan on login/logoff
O(N) per event with N up to 500. MEDIUM, 437x at L=2000.
wesnoth-0003: combine_special_notes O(N^2) vector dedup
utils::contains on vector per note insertion. MEDIUM, 499x at N=1000.
MOAD-0002 (Intertangle): singletons deeply embedded, not actionable.
MOAD-0003 (Leaked Context): thread_local for debug/call-stack only.
MOAD-0004 (Logged Secret): passwords never logged verbatim.
MOAD-0005 (Thundering Herd): single-threaded game + coroutine server.
6/6 unit tests PASS.
AppConfig.__getattr__ logs raw decoded values when config keys change
via Redis, including OPENAI_API_KEYS, GOOGLE_CLIENT_SECRET, and 20+
other API key/token/password PersistentConfig entries. Fix: redact
values for keys matching SECRET/KEY/TOKEN/PASSWORD/CREDENTIAL denylist.
13/13 PASS
monogame-0001: IntermediateWriter.WriteSharedResources writtenSharedResources
List<string>.Contains in while loop O(R^2), fix: HashSet<string> MEDIUM
monogame-0002: IntermediateSerializer._scannedObjects List<object>.Contains
per object during scan O(N^2), fix: HashSet<object> MEDIUM
monogame-0003: OpenAssetImporter._bones List<Node>.Contains in recursive
tree import O(N*B), fix: HashSet<Node> MEDIUM
MOAD-0002 through 0005: CLEAN (single-threaded game framework, no secrets,
no leaked context, no thundering herd)
sparrow-0001: WalletUtxosEntry.updateUtxos() ArrayList.removeAll O(N^2)
UTXO diff uses List.removeAll which is O(current * previous).
Fix: Set-based diff via Sets.difference (same pattern already used
in WalletTransactionsEntry). MEDIUM, 250x at N=1000 UTXOs.
sparrow-0002: UtxoEntry.recountMixesDone stream().anyMatch O(M*I*T)
Whirlpool mix chain walk streams all wallet TXOs per input per mix.
Fix: HashMap<Sha256Hash, Set<Long>> index for O(1) lookup.
MEDIUM-HIGH, 50x at M=200 mixes, T=1000 TXOs.
MOAD-0002 (Intertangle): EventManager is a thin Guava EventBus singleton,
not a god object. Wallet/network/UI coupling is event-driven, acceptable.
MOAD-0003 (Leaked Context): CLEAN, no ThreadLocal usage found.
MOAD-0004 (Logged Secret): CLEAN, no private keys/mnemonics/passphrases
logged. SecureChannelSession has commented-out secret logging.
MOAD-0005 (Thundering Herd): CLEAN, no unsynchronized cache patterns.
4/4 unit tests PASS. UNDF-2026-000000931 through UNDF-2026-000000932.
CWE-407 array scans exist but bounded by Bitcoin consensus (p2ms max
n=20, taptree max depth 128). No adversarial scaling possible.
No intertangle, leaked context, logged secrets, or thundering herd.