java-topology/whitepaper/outreach/netpanzer-0001.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 Permalink Blame History

NetPanzer — CWE-407 Disclosure Brief (netpanzer-0001)

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

Finding

One O(n) defect in NetPanzer's unit removal from player unit lists. Patched. UnitInterface::removeUnit() uses std::find() on a vector to locate a unit for removal, producing O(U) per removal where U = player unit count.

The Defect

netpanzer-0001 (PATCHED — MEDIUM): src/NetPanzer/Units/UnitInterface.cpp:165

// In removeUnit() — fires per unit destruction:
PlayerUnitList::iterator pi = std::find(plist.begin(), plist.end(), unit);
assert(pi != plist.end());
if (pi != plist.end()) plist.erase(pi);

PlayerUnitList is a std::vector<UnitBase*>. std::find() is O(U) and erase() from the middle is also O(U). Combined: O(U) per unit removal. With many units destroyed in rapid succession (battle), total cost compounds.

Complexity Proof

At U=500 units per player:

  • Defective: O(500) find + O(500) shift per removal
  • Fixed: O(1) index lookup + O(1) swap-and-pop
  • ~500× op reduction per unit removal.

Impact

NetPanzer is an open-source multiplayer tank battle game. Unit destruction happens frequently during combat. With hundreds of units per player in large battles, the linear find-and-erase on every destruction event degrades frame rate during intense combat.

The Fix

Maintain an unordered_map<UnitBase*, size_t> index for O(1) lookup, use swap-and-pop for O(1) removal:

// Before: O(U) find + O(U) erase
auto pi = std::find(plist.begin(), plist.end(), unit);
plist.erase(pi);

// After: O(1) index lookup + swap-and-pop
auto it = playerUnitIndex.find(unit);
size_t idx = it->second;
plist[idx] = plist.back();
playerUnitIndex[plist.back()] = idx;
plist.pop_back();
playerUnitIndex.erase(it);

Patch

Fix available: defects/netpanzer-0001/patch/

Touches UnitInterface.hpp and UnitInterface.cpp. ~500× speedup per unit removal at 500 units.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a GitHub issue reference.
  2. Assess severity — fires on every unit destruction during combat.
  3. Coordinate a disclosure date — we are targeting 90 days from first contact.
  4. We will credit the NetPanzer team in the public disclosure. Preferred acknowledgment format welcome.

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