From ccede712916f3b9f495138bf67f744735dacef7e Mon Sep 17 00:00:00 2001 From: Simon Date: Wed, 26 Nov 2025 11:00:30 +0900 Subject: [PATCH] Fix ClassDB crash caused by HashMap reallocation invalidating parent_ptr --- include/godot_cpp/core/class_db.hpp | 7 ------- src/core/class_db.cpp | 24 ++++++++++++++++++++---- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/include/godot_cpp/core/class_db.hpp b/include/godot_cpp/core/class_db.hpp index b14f597a2..1a2b5f9d7 100644 --- a/include/godot_cpp/core/class_db.hpp +++ b/include/godot_cpp/core/class_db.hpp @@ -90,8 +90,6 @@ class ClassDB { AHashMap virtual_methods; std::set property_names; std::set constant_names; - // Pointer to the parent custom class, if any. Will be null if the parent class is a Godot class. - ClassInfo *parent_ptr = nullptr; }; private: @@ -233,11 +231,6 @@ void ClassDB::_register_class(bool p_virtual, bool p_exposed, bool p_runtime) { cl.name = T::get_class_static(); cl.parent_name = T::get_parent_class_static(); cl.level = current_level; - AHashMap::Iterator parent_it = classes.find(cl.parent_name); - if (parent_it != classes.end()) { - // Assign parent if it is also a custom class - cl.parent_ptr = &parent_it->value; - } classes[cl.name] = cl; class_register_order.push_back(cl.name); diff --git a/src/core/class_db.cpp b/src/core/class_db.cpp index 11f7b0778..9b8ecbe70 100644 --- a/src/core/class_db.cpp +++ b/src/core/class_db.cpp @@ -118,8 +118,13 @@ MethodBind *ClassDB::get_method(const StringName &p_class, const StringName &p_m if (method != type->method_map.end()) { return method->value; } - type = type->parent_ptr; - continue; + + AHashMap::Iterator parent_it = classes.find(type->parent_name); + if (parent_it == classes.end()) { + break; + } + + type = &parent_it->value; } return nullptr; @@ -243,7 +248,13 @@ void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) ClassInfo *check = &cl; while (check) { ERR_FAIL_COND_MSG(check->signal_names.find(p_signal.name) != check->signal_names.end(), String("Class '{0}' already has signal '{1}'.").format(Array::make(p_class, p_signal.name))); - check = check->parent_ptr; + + AHashMap::Iterator parent_it = classes.find(check->parent_name); + if (parent_it == classes.end()) { + break; + } + + check = &parent_it->value; } // register our signal in our plugin @@ -303,7 +314,12 @@ GDExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, GDExtens return method_it->value.func; } - type = type->parent_ptr; + AHashMap::Iterator parent_it = classes.find(type->parent_name); + if (parent_it == classes.end()) { + break; + } + + type = &parent_it->value; } return nullptr;