java-topology/whitepaper/outreach/pcsx2-0003.md
russell@unturf.com 652608142a feat: close outreach doc gap — 276 docs (batches 11-16)
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.
2026-04-15 13:57:42 -04:00

2.3 KiB
Raw Blame History

PCSX2 — CWE-407 Disclosure Brief (pcsx2-0003)

2026-04-13 · Patch available — awaiting upstream merge

Finding

O(A²) badge path lookup in Achievements::DrawAchievement() where std::find_if scans a vector<pair<const void*, string>> for every achievement drawn each frame.

The Defect

pcsx2-0003 (PATCHED — MEDIUM): pcsx2/Achievements.cpp:2774

static std::vector<std::pair<const void*, std::string>> s_achievement_badge_paths;

// DrawAchievement — fires per achievement per frame:
if (const auto badge_it = std::find_if(
        s_achievement_badge_paths.begin(), s_achievement_badge_paths.end(),
        [cheevo](const auto& it) { return (it.first == cheevo); });
    badge_it != s_achievement_badge_paths.end())
{
    badge_path = &badge_it->second;
}

Each achievement drawn scans the entire badge path vector. With A achievements visible, cost per frame is O(A²).

Complexity Proof

At A=200 achievements (common for RetroAchievements-enabled games):

  • Defective: ~20,000 pointer comparisons per frame
  • Fixed: 200 hash lookups per frame
  • ~100× op reduction per frame.

Impact

PCSX2 integrates with RetroAchievements for progress tracking. Achievement overlays and notification popups call DrawAchievement() per visible achievement. Games with 200+ achievements compound the per-frame cost. At 60 fps, 1.2 million unnecessary comparisons per second.

The Fix

Replace vector<pair> with unordered_map<const void*, string>:

static std::unordered_map<const void*, std::string> s_achievement_badge_paths;
// ...
if (const auto badge_it = s_achievement_badge_paths.find(cheevo);
    badge_it != s_achievement_badge_paths.end())
    badge_path = &badge_it->second;

Patch

Fix available: defects/pcsx2-0003/patch/pcsx2-0003-achievements-badge-paths-map.patch

Single-file patch in Achievements.cpp.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a GitHub issue reference (PCSX2/pcsx2).
  2. Assess severity — per-frame overhead scaling with achievement count.
  3. Coordinate a disclosure date — we target 90 days from first contact.
  4. We will credit the PCSX2 team in the public disclosure. Preferred acknowledgment format welcome.

Contact: see cover email. This brief is confidential until coordinated disclosure.