java-topology/whitepaper/outreach/cocos2d-0002.md
russell@unturf.com aeb084c9ae feat: add 30 outreach docs (batches 9-10)
Batch 9 (15): bun, bzflag (3), cake_wallet (4), calligra, caprice32 (2),
  cataclysm (3), cemu
Batch 10 (15): cemu-0002, citra, clickhouse-java, cmake (3), cocos2d (3),
  conduit, cura (2), curaengine, clamav, contiki
2026-04-14 19:51:36 -04:00

2.6 KiB
Raw Blame History

Cocos2d-x — CWE-407 Disclosure Brief (cocos2d-0002)

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

Finding

One O(n²) defect in Cocos2d-x in the physics world joint management. std::find() over _joints (a std::vector<PhysicsJoint*>) fires on every collision callback during physics simulation. Patched.

The Defects

cocos2d-0002 (PATCHED — HIGH): cocos/physics/CCPhysicsWorld.cpp:310 and CCPhysicsWorld.h

// In collisionBeginCallback — fires per physics collision per tick:
for (PhysicsJoint* joint : jointsA)
{
    if (std::find(_joints.begin(), _joints.end(), joint) == _joints.end())  // O(J) scan
    {
        continue;
    }
    ...
}

_joints is std::vector<PhysicsJoint*>. Every collision callback checks whether each joint attached to the colliding bodies exists in the world's joint list. std::find() is O(J) where J = total joints in the world. For C collisions per tick with A joints per body: O(C × A × J) per physics tick.

Complexity Proof

At J=100 world joints, C=50 collisions per tick, A=3 joints per body:

  • Defective: 50 × 3 × 100 = 15,000 comparisons per physics tick
  • Fixed: 50 × 3 × 1 = 150 hash lookups
  • 100× op reduction per tick. At 60 Hz: 900,000 comparisons/sec eliminated.

Impact

Cocos2d-x physics simulation drives collision detection and response in thousands of mobile games. Games with many jointed bodies (ragdoll characters, chain/rope physics, destructible environments) accumulate joints rapidly. Every collision event checks joint validity against the world list, making physics-heavy games disproportionately affected.

The Fix

Add an std::unordered_set<PhysicsJoint*> shadow index alongside _joints:

// Before
std::vector<PhysicsJoint*> _joints;
std::find(_joints.begin(), _joints.end(), joint)

// After — O(1) membership via shadow set
std::unordered_set<PhysicsJoint*> _jointsSet;
_jointsSet.find(joint)
// Maintain _jointsSet on insert/remove alongside _joints vector.

Patch

Fix available: defects/cocos2d-0002/patch/cocos2d-0002.patch

Two-file patch across CCPhysicsWorld.h and CCPhysicsWorld.cpp.

Unit test: pass. 100× op reduction at 100 joints.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign a GitHub issue reference (cocos2d/cocos2d-x).
  2. Assess severity — fires on every physics collision callback, per tick, in jointed scenes.
  3. Coordinate a disclosure date — we are targeting 90 days from first contact.
  4. We will credit the Cocos2d-x team in the public disclosure. Preferred acknowledgment format welcome.

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