MOAD-0001 (CWE-407): SubCheatsRead in src/cheat.cpp scans all C active
cheats linearly on every NES memory read at any cheat address. O(C) per
read, C up to 256. Fix: cheat_idx[0x10000] direct address lookup, O(1).
Unit test: 74.7x speedup at C=256. 1/1 PASS.
MOAD-0002: Global mutable state (SubCheats[], ARead[], CheatRPtrs[])
couples cheat, PPU, CPU subsystems -- expected single-threaded NES
architecture, not an actionable intertangle defect.
MOAD-0003: thread_local in profiler.cpp (per-thread profiling data) and
QtScriptManager.cpp (per-JS-engine context pointer) -- legitimate
thread-local scoping, not a leaked request context carrier.
MOAD-0004: NetPlay.cpp line 788 logs netplay session password verbatim
via printf("Authorize: Player: %i Passwd: %s\n", msg->playerId,
msg->pswd). Debug printf, no patch created per scan protocol (0001 only).
MOAD-0005: No cache get+null+compute+put races found. CLEAN.
sameboy-0001: test_watchpoint() O(W) linear scan per GB memory read/write.
Every call to GB_read_memory / GB_write_memory scans all watchpoints when
n_watchpoints > 0. Fix: watchpoint_address_flags[0x10000] lookup table gives
O(1) early exit; 128x speedup at W=128.
sameboy-0002: should_break() O(B) linear scan per CPU instruction fetch.
GB_debugger_run() calls should_break() every instruction when debug_active.
Fix: breakpoint_address_set[0x10000] boolean table gives O(1) early exit;
128x speedup at B=128.
MOAD-0002: CLEAN, gb struct passed explicitly, no shared global state.
MOAD-0003: CLEAN, __thread only used for local string formatting buffers.
MOAD-0004: CLEAN, no network credentials logged.
MOAD-0005: CLEAN, no unsynchronized cache patterns found.
samba-0001: security_token_has_sid O(A*S) in se_access_check
- security_token_has_sid() does O(S) linear scan over token SIDs
- called inside O(A) ACE loop in se_access_check_implicit_owner()
- O(A*S) per file access; S=200 groups, A=20 ACEs = 4000 comparisons
- fix: sort token->sids[2..] at finalization, use bsearch for O(log S)
- 9.5x measured speedup (S=200, A=20); up to 26x at S=200, A=50
- hot path: called on every smbd file open / access check
samba-0002: security_token_create O(N^2) SID dedup (source4 AD DC path)
- nested for-loop in security_token_create deduplicates SIDs O(N^2)
- Kerberos PAC with 500 group SIDs: ~125,000 dom_sid_equal() calls/login
- at MS-KILE 1015-SID limit: ~515,000 calls per DC login
- fix: binary insertion sort scratch array for O(N log N) dedup
- 5.7x speedup at N=500, 9.3x at N=1000 (near PAC limit)
- also applies security_token_sort_sids() after token build
MOAD-0002: smbd is single-threaded event loop, global state is by design
MOAD-0003: no thread-local credential storage found
MOAD-0004: all sensitive dumps guarded by #ifdef DEBUG_PASSWORD compile flag
MOAD-0005: all caches TDB-synchronized or single-threaded event loop
MOAD-0001 (CWE-407): filterMetrics() in allocate.go calls containsPeer()
(linear scan) three times per metric in our inner loop — once for blacklist,
once for currentAllocs, once for priorityList. With M metrics and B+C+P
total peer-list entries, each allocation decision costs O(M*(B+C+P)).
Fix: Build map[peer.ID]struct{} sets before our loop. Each lookup becomes O(1).
At scale (200 peers, 100-entry lists): ~60x fewer comparisons.
MOAD-0002 (intertangle): allocation state passed as function args, no globals. CLEAN.
MOAD-0003 (leaked context): no ThreadLocal or goroutine-scoped carriers. CLEAN.
MOAD-0004 (logged secret): peer IDs logged, no auth tokens or private keys. CLEAN.
MOAD-0005 (thundering herd): allocation runs under consensus lock. CLEAN.
lotus-0001: eventFilter.matchAddress() slices.Contains O(A) per event,
replace with map[address.Address]struct{} for O(1) lookup; 28.6x at A=100,
225x at A=1000; no limit enforced on Addresses in EthFilterSpec
nfs-utils-0001: client_lookup() non-FQDN branch O(N) linked list
scan per call in support/export/client.c:289. With N unique
wildcard/netgroup/subnet clients, export_read totals O(N^2).
Fix: hash table for hostname lookup. 119x at N=4000.
nfs-utils-0002: get_exportlist() in utils/mountd/mountd.c,
lookup_or_create_elist_entry O(E) path scan + insert_group
O(G) dedup scan, both per export = O(E^2) total. Fix: hash
tables for path lookup and group dedup. 73x at N=4000.
MOAD-0002 (intertangle): clientlist/exportlist globals are standard
single-threaded daemon design, single execution context. CLEAN.
MOAD-0003 (leaked context): no __thread or pthread_getspecific. CLEAN.
MOAD-0004 (logged secret): gssd logs keytab paths and principal
names (not credentials). No key material logged. CLEAN.
MOAD-0005 (thundering herd): caches protected by ple_lock mutex
in gssd, single-threaded event loop in mountd. CLEAN.
s3fs-fuse-0001: StatCache::RawGetChildStats() dedup uses std::find()
on std::vector<std::string> inside loop over childmap. O(N*M) on every
readdir() and rename_directory() call. Fix: unordered_set for O(1)
lookup. MEDIUM severity, 13.8x at N=2000/M=1000.
MOAD-0002 (intertangle): globals are config-only, set at startup.
Subsystems (stat cache, fd cache, curl) are properly isolated
behind singleton + mutex. CLEAN.
MOAD-0003 (leaked context): no thread_local usage found. CLEAN.
MOAD-0004 (logged secret): all credential logging uses
mask_sensitive_string(). insecure_logging is opt-in and deprecated.
CLEAN.
MOAD-0005 (thundering herd): stat cache uses std::mutex properly.
curl handle pool uses lock_guard. No unprotected cache paths. CLEAN.
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