31 lines
1.5 KiB
Diff
31 lines
1.5 KiB
Diff
# UNDF: UNDF-2026-000000779
|
||
# UNDF: (leave blank)
|
||
# CWE-407: usd_skel_convert.cc used_indices dedup via std::find — O(J^2)
|
||
#
|
||
# When importing USD skeletal meshes, the code iterates over all joint_indices
|
||
# (one per vertex weight) and builds a unique list of used joint indices using
|
||
# std::find() on a Vector<int> for deduplication. This is O(J) per check,
|
||
# O(J^2) total where J = number of joint weight entries.
|
||
#
|
||
# For high-poly meshes with many bone influences, J can be very large
|
||
# (vertices × influences_per_vertex, easily 100k+).
|
||
#
|
||
# Fix: use a Set<int> for O(1) dedup, then convert to vector for downstream use.
|
||
#
|
||
# Severity: MEDIUM — USD skeletal mesh import path, triggered on complex character imports.
|
||
# Overhead: ~250x at J=1000 joint weight entries.
|
||
#
|
||
--- a/source/blender/io/usd/intern/usd_skel_convert.cc
|
||
+++ b/source/blender/io/usd/intern/usd_skel_convert.cc
|
||
@@ -1134,8 +1134,9 @@
|
||
|
||
/* Determine which joint indices are used for skinning this prim. */
|
||
- Vector<int> used_indices;
|
||
+ Set<int> used_indices_set;
|
||
+ Vector<int> used_indices; /* ordered list for downstream use */
|
||
for (int index : joint_indices.AsConst()) {
|
||
- if (std::find(used_indices.begin(), used_indices.end(), index) == used_indices.end()) {
|
||
+ if (used_indices_set.add(index)) {
|
||
/* We haven't accounted for this index yet. */
|
||
if (index < 0 || index >= joints.size()) {
|
||
CLOG_ERROR(&LOG, "Out of bound joint index %d for mesh %s", index, mesh_obj->id.name + 2);
|