# libGDX — CWE-407 Disclosure Brief
**2026-03-27 · Patch available — awaiting upstream merge**

## Finding

Four O(n²) defects in libGDX's 3D model loading, reference building, instancing, and font kerning systems. The most severe (libgdx-0004) affects font loading with a 1,971× measured overhead from O(coverage×classes×K) kerning lookups. Patches ready for upstream review.

## The Defects

**libgdx-0001 (PATCHED — HIGH):** `Model.java:190`

```java
// Inside loadNode() per model node:
// Nested string-ID scan for meshPart and material:
for (ModelMeshPart meshPart : model.meshes) {       // O(meshes)
    for (ModelMeshPart part : node.parts) {         // O(parts)
        if (meshPart.id.equals(part.meshPartId)) {  // O(meshes×parts)
```

Nested scan to find meshPart and material by string ID per model node. **O(parts × (meshes + materials))**. **Measured ratio: 150×.**

**libgdx-0002 (PATCHED — MEDIUM):** `ModelBuilder.java:371`

```java
// Inside rebuildReferences():
if (meshParts.contains(part)) { ... }  // Array.contains() ×3
```

`Array.contains()` called ×3 during `rebuildReferences()`. **O(parts × materials)**. **Measured ratio: 25×.**

**libgdx-0003 (PATCHED — MEDIUM):** `ModelInstance.java`

```java
// Inside invalidate() per node-part per model spawn:
if (nodes.contains(node)) { ... }  // Array.contains() per node
```

`Array.contains()` scan per node-part during `invalidate()`. Called on every model instance spawn. **O(parts × materials)**. **Measured ratio: 25×.**

**libgdx-0004 (PATCHED — HIGH):** `Kerning.java`

```java
// Inside GPOS type-2 coverage loop during font load:
if (intArray.contains(glyphId)) { ... }  // IntArray.contains() per glyph
```

`IntArray.contains()` O(coverage) scan per glyph class per kerning pair during font loading. For coverage C, classes K, and pairs P: **O(coverage × classes × K)**. **Measured ratio: 1,971×.**

## Complexity Proof

**libgdx-0001:** **150× measured ratio** on models with many mesh parts and materials.

**libgdx-0002/0003:** **25× measured ratio** each — O(parts×materials) per model operation.

**libgdx-0004:** For C=200 coverage entries, K=100 kerning pairs:
- Defective: C×K = 20,000 comparisons per font load
- Fixed: reverse `IntIntMap` → O(1) per lookup
- **1,971× measured ratio.**

## Impact

All libGDX applications loading 3D models (libgdx-0001/0002/0003) and all applications rendering text with OpenType GPOS kerning (libgdx-0004). libGDX is a widely used cross-platform Java game development framework. Games with many 3D assets or rich typography hit these defects on asset load. libgdx-0004 is particularly impactful for UI-heavy games and apps with many font glyphs.

## The Fix

**libgdx-0001:** Pre-build `Map<String, ModelMeshPart>` and `Map<String, ModelMaterial>` indexes before the nested loop.

**libgdx-0002/0003:** Replace `Array` with `ObjectSet` for `meshParts`/`nodes` dedup collections.

**libgdx-0004:** Build a reverse `IntIntMap<glyphId, classIndex>` before the coverage loop:

```java
// Before
if (intArray.contains(glyphId)) { ... }  // O(coverage) per glyph

// After
// CWE-407 fix: IntIntMap for O(1) lookup instead of O(coverage) IntArray scan.
if (glyphToClass.containsKey(glyphId)) { ... }
```

## Patch

`defects/libgdx/patch/libgdx-0001-0002-0003-0004-model-kerning-maps.patch`

## What We Ask

1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
2. Validate the patch against your model loading and font rendering test suites.
3. Assess CVE eligibility — libgdx-0004 measured at 1,971× on font loading.
4. Coordinate a disclosure date — we are targeting 90 days from first contact.

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