java-topology/defects/libgdx/patch/libgdx-0002-model-builder-rebuild-refs-o-n2.patch

44 lines
2.2 KiB
Diff

# UNDF: UNDF-2026-000000449
# UNDF:
--- a/gdx/src/com/badlogic/gdx/graphics/g3d/utils/ModelBuilder.java
+++ b/gdx/src/com/badlogic/gdx/graphics/g3d/utils/ModelBuilder.java
@@ -361,18 +361,30 @@
/** Resets the references to {@link Material}s, {@link Mesh}es and {@link MeshPart}s within the model to the ones used within
* it's nodes. This will make the model responsible for disposing all referenced meshes. */
public static void rebuildReferences (final Model model) {
model.materials.clear();
model.meshes.clear();
model.meshParts.clear();
- for (final Node node : model.nodes)
- rebuildReferences(model, node);
+ // CWE-407 fix: build identity-keyed ObjectSets before recursion to avoid O(P*M) Array.contains().
+ ObjectSet<Object> seenMaterials = new ObjectSet<>();
+ ObjectSet<Object> seenMeshParts = new ObjectSet<>();
+ ObjectSet<Object> seenMeshes = new ObjectSet<>();
+ for (final Node node : model.nodes)
+ rebuildReferences(model, node, seenMaterials, seenMeshParts, seenMeshes);
}
- private static void rebuildReferences (final Model model, final Node node) {
+ private static void rebuildReferences (final Model model, final Node node,
+ final ObjectSet<Object> seenMaterials, final ObjectSet<Object> seenMeshParts,
+ final ObjectSet<Object> seenMeshes) {
for (final NodePart mpm : node.parts) {
- if (!model.materials.contains(mpm.material, true)) model.materials.add(mpm.material);
- if (!model.meshParts.contains(mpm.meshPart, true)) {
+ // Previously: Array.contains() is O(M) called per NodePart → O(P*M) total.
+ // Fix: ObjectSet.add() returns false if already present → O(1) per check.
+ if (seenMaterials.add(mpm.material)) model.materials.add(mpm.material);
+ if (seenMeshParts.add(mpm.meshPart)) {
model.meshParts.add(mpm.meshPart);
- if (!model.meshes.contains(mpm.meshPart.mesh, true)) model.meshes.add(mpm.meshPart.mesh);
+ if (seenMeshes.add(mpm.meshPart.mesh)) model.meshes.add(mpm.meshPart.mesh);
model.manageDisposable(mpm.meshPart.mesh);
}
}
for (final Node child : node.getChildren())
- rebuildReferences(model, child);
+ rebuildReferences(model, child, seenMaterials, seenMeshParts, seenMeshes);
}
@@ -1,3 +1,4 @@
+import com.badlogic.gdx.utils.ObjectSet;