You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fixes 12 algorithmic complexity defects (CWE-407) across Redot Engine.
All defects use Vector::has() or Vector::find() as membership/lookup tests
inside hot loops, giving O(N²) cost. Each fix adds a HashSet or HashMap
shadow index for O(1) lookups while preserving the original Vector.
redot-0001 scene/main/scene_tree.cpp
Group::nodes.has(p_node) — O(n) per add_to_group(), fires every frame.
Fix: HashSet<Node*> node_set shadow in struct Group. 1,000x at n=2,000.
redot-0002 modules/godot_physics_2d/godot_body_2d.h
areas.find(AreaCMP(p_area)) — O(n) per physics tick in 2D area overlap.
Fix: HashMap<RID,int> area_index shadow. 50x at 500 bodies x 200 areas.
redot-0003 modules/godot_physics_3d/godot_body_3d.h
Same as redot-0002, 3D physics variant. 50x speedup.
redot-0004 modules/godot_physics_3d/godot_soft_body_3d.cpp
node_links[ia].has(ib) — O(n) per link in bending constraint generation.
Fix: LocalVector<HashSet<int>> node_link_set shadow per node.
redot-0005 core/math/a_star.cpp + a_star_grid_2d.cpp
open_list.find(e) — O(N) per neighbor relaxation in A* decrease-key path.
Fix: open_index field on Point; maintained on push/pop. O(N²) -> O(N log N).
Affects AStar3D, AStar2D, AStarGrid2D.
redot-0006 scene/3d/skeleton_3d.cpp
child_bones.has(i) — O(B) per bone in _update_process_order().
Fix: child_bones changed from Vector<int> to HashSet<int>.
redot-0007 editor/import/3d/post_import_plugin_skeleton_rest_fixer.cpp
Two Vector<int>-as-sets: bones_to_process and keep_bone_rest.
Both call .has() inside track loops. Fix: both to HashSet<int>.
redot-0008 modules/gltf/gltf_state.h + gltf_document.cpp + gltf_state.cpp
extensions_used — Vector<String>.has() O(E) per node/animation/track.
Fix: HashSet<String>. insert() is idempotent O(1). All callers updated.
redot-0009 scene/resources/font.cpp
Font::_is_cyclic() — no visited set, O(F^D) on diamond fallback graphs.
Fix: HashSet<const Font*> visited threaded via _is_cyclic_internal().
redot-0010 scene/resources/font.cpp
Font::_update_rids_fb() — no visited set, O(N²) diamond re-traversal.
Fix: HashSet<const Font*>* r_visited param. FontVariation + SystemFont fixed.
redot-0011 scene/gui/graph_edit_arranger.cpp
ORDER and PRED macros use Vector::find() — O(N) per connection.
Fix: pre-build HashMap<StringName,int> node_order and
HashMap<StringName,StringName> predecessor_map. O(C*N) -> O(N+C).
redot-0012 scene/3d/spring_bone_simulator_3d.cpp
collisions.has(id) and collisions.find(id) — O(N) inside S*C loops per tick.
Fix: HashSet<ObjectID> collision_set + HashMap<ObjectID,int> collision_index_map.
O(S*C*N) -> O(N + S*C) per tick.
All fixes use Redot's own HashSet<T> and HashMap<K,V> from core/templates/.
No new dependencies. Vectors preserved where ordered iteration is needed.
Discovered by undefect.com — CWE-407 sedimentary defect campaign.
Contact: security@undefect.com
0 commit comments