# AngelScript — CWE-407 Disclosure Brief **2026-03-27 · Patch available — awaiting upstream merge** ## Finding Three O(n²) defects in AngelScript's module ownership transfer and switch-statement compiler. All patched. Patches ready for upstream review. Notably, the AngelScript source contains explicit `// TODO: optimize` comments at two of the defect sites, acknowledging the performance problem. ## The Defects **angelscript-0001 (PATCHED — HIGH):** `sdk/angelscript/source/as_scriptengine.cpp:880` ```cpp // In FindNewOwnerForSharedType() — called per shared type on module discard: for (int n = 0; n < engine->modules.GetLength(); n++) { asCModule *mod = engine->modules[n]; // 5 calls to IndexOf() per shared type transfer: if (mod->sharedTypes.IndexOf(type) >= 0) { ... } // O(n) per call } // Engine comment at line 917: // "TODO: optimize: If the modules already stored the shared types separately, this would be quicker" ``` `asCArray::IndexOf()` is a linear scan. Called 5 times per shared type transfer for every remaining module. **angelscript-0002 (PATCHED — HIGH):** `sdk/angelscript/source/as_scriptengine.cpp:953` ```cpp // In FindNewOwnerForSharedFunc() — called per shared function on module discard: if (mod->sharedFunctions.IndexOf(func) >= 0) { ... } // O(n) per call ``` Same root cause on shared functions. 5 linear scans per shared function transfer. **angelscript-0003 (PATCHED — HIGH):** `sdk/angelscript/source/as_compiler.cpp` ```cpp // In CompileSwitch() — per case value in while loop: while (/* more cases */) { if (caseValues.IndexOf(caseVal) >= 0) { // O(n) per case — duplicate check Error(TXT_DUPLICATE_SWITCH_CASE); } caseValues.PushLast(caseVal); } // O(n²) duplicate case detection during switch compilation ``` `caseValues` is `asCArray`. `IndexOf()` is O(n) per case. O(n²) total for n switch cases. ## Complexity Proof **angelscript-0001/0002:** For T shared types/functions across M modules: - Per module: 5 × O(T) `IndexOf()` calls - Total: **O(M × T × 5)** At T=200 types, M=100 modules: defective=3,980,000 comparisons, fixed=39,800 (`asCSet<>` shadow). **100× op reduction.** **angelscript-0003:** For N case values in a switch statement: - Per case: O(N) `IndexOf()` scan - Total: **O(N²)** At N=500 cases: defective=124,750 comparisons, fixed=500 (`asCSet` shadow). **250× op reduction.** ## Impact AngelScript is the scripting language embedded in many C++ game engines and applications, including Dry/Urho3D, and dozens of indie engines. It is used wherever C++ developers need a scripting layer that integrates tightly with C++ types. angelscript-0001/0002 fire on every `module->Discard()` call — when a script module is unloaded and ownership of shared types/functions must be transferred. In applications that frequently reload scripts (modding systems, live editing workflows, hot-reload dev environments), this path runs repeatedly. angelscript-0003 fires on every script compilation that includes a switch statement. Scripts with large switch statements (state machines, command parsers, opcode dispatchers) pay O(n²) at every compile. For switch statements with hundreds of cases (common in protocol implementations and scripted state machines), the overhead is significant. ## The Fix **angelscript-0001/0002:** Add `asCSet` and `asCSet` shadow sets: ```cpp // Before if (mod->sharedTypes.IndexOf(type) >= 0) { ... } // After // CWE-407 fix: asCSet shadow for O(1) Exists() instead of O(n) IndexOf() scan. if (mod->sharedTypeSet.Exists(type)) { ... } ``` Maintain `sharedTypeSet` and `sharedFuncSet` alongside the existing arrays. `asCSet` is already available in AngelScript's own container library. **angelscript-0003:** Add `asCSet` for case dedup: ```cpp // Before if (caseValues.IndexOf(caseVal) >= 0) { ... } caseValues.PushLast(caseVal); // After // CWE-407 fix: asCSet for O(1) duplicate detection instead of O(n) IndexOf(). if (caseValueSet.Exists(caseVal)) { ... } caseValueSet.Insert(caseVal); caseValues.PushLast(caseVal); // preserved for downstream iteration ``` ## Patch Fix available: `defects/angelscript/patch/angelscript-0001-0003-ascset-shadow.patch` Three-location patch across `as_scriptengine.cpp` (two sites) and `as_compiler.cpp`. Unit test: `AngelScriptTest` 4/4 pass. angelscript-0001/0002: **100× speedup at T=200, M=100**. angelscript-0003: **250× speedup at N=500 cases**. ## What We Ask A patch is ready for review. 1. Confirm receipt and assign an issue reference (AngelCode/angelscript or the official forums). 2. Assess severity — the `// TODO: optimize` comments in the source indicate these defects were already known; the patch resolves them. 3. Coordinate a disclosure date — we are targeting 90 days from first contact. 4. We will credit the AngelScript team in the public disclosure. Preferred acknowledgment format welcome. Contact: see cover email. This brief is confidential until coordinated disclosure.