cmake-0005: cmQtAutoGen MergeOptions std::find over baseOpts in newOpts loop, O(N*M), 31.5x at N=M=50 cmake-0006: cmVisualStudio10TargetGenerator FinishWritingSource writtenSettings O(S^2), 15.3x at S=30 cmake-0007: cmGeneratorExpressionNode TargetRuntimeDllDirsNode dllDirs O(D^2), 10.3x at D=100 MPD: all 5 MOADs CLEAN; updated CLEAN.md with MOAD-0002 through MOAD-0005 analysis. Unit tests: 3/3 PASS.
52 lines
2.3 KiB
Markdown
52 lines
2.3 KiB
Markdown
# MPD (Music Player Daemon) - 5-MOAD Scan Result: CLEAN
|
|
|
|
Scanned: 2026-03-30 (CWE-407), updated 2026-03-31 (all 5 MOADs)
|
|
Source: https://github.com/MusicPlayerDaemon/MPD (depth=1)
|
|
|
|
## MOAD-0001 (CWE-407): CLEAN
|
|
|
|
MPD is well-engineered with respect to data structure choices:
|
|
|
|
- **Tag type lookups**: Uses bitmask arrays (`TagMask`) for O(1) membership testing
|
|
- **Protocol list**: Uses `std::set` for dedup
|
|
- **Property model**: Uses `g_hash_table` (via libmpd) for O(1) lookups
|
|
- **Keyword tracking**: Uses `g_hash_table` for entry-keyword mapping
|
|
- **Playlist dedup**: Uses hash-based `location_in_map` via `g_hash_table`
|
|
- **Input cache**: Uses `std::map` (`items_by_uri`) for URI lookups
|
|
- **Event polling**: Uses `std::map` for fd-to-pollfd mapping
|
|
- **Client subscriptions**: Uses `std::set<std::string>` for channel tracking
|
|
- **Permission passwords**: Uses `std::map<std::string, unsigned>` for O(log N) lookup
|
|
|
|
The few `std::find` calls found operate on bounded-size collections
|
|
(tag_types, ~30 entries max) and are not inside scaling loops.
|
|
|
|
No CWE-407 defects found.
|
|
|
|
## MOAD-0002 (Intertangle): CLEAN
|
|
|
|
`global_instance` is a single-owner pointer set once at startup and read-only
|
|
during operation. MPD uses an event-loop architecture (single main thread +
|
|
worker threads with explicit queues), avoiding shared mutable god objects.
|
|
|
|
## MOAD-0003 (Leaked Context): CLEAN
|
|
|
|
MPD is C++ without Java-style ThreadLocal or Python ContextVar patterns.
|
|
Worker threads receive per-task context through explicit parameters and
|
|
event queue payloads, not thread-scoped globals carrying request identity.
|
|
|
|
## MOAD-0004 (CWE-312): CLEAN
|
|
|
|
- `CurlInputPlugin.cxx` installs `CurlDebugToLog` as `CURLOPT_DEBUGFUNCTION`,
|
|
which logs `CURLINFO_HEADER_OUT` (outgoing headers) only when
|
|
`verbose = true` in `mpd.conf`. This is an explicit operator opt-in to
|
|
debug logging, not a default credential leak. No unconditional credential
|
|
logging found.
|
|
- Qobuz login sends password as a URL query parameter (per Qobuz API design),
|
|
but no MPD code logs our login URL verbatim.
|
|
- `Permission.cxx` stores passwords in a `std::map` and never logs them.
|
|
|
|
## MOAD-0005 (Thundering Herd): CLEAN
|
|
|
|
MPD's input cache (`src/input/cache/Manager.cxx`) uses a mutex-protected
|
|
`std::map` for all cache operations. No unsynchronized get+null+set patterns
|
|
found. Worker thread access goes through locked event dispatch.
|