Skip to content

Commit

Permalink
Fix use-after-free at shutdown
Browse files Browse the repository at this point in the history
  • Loading branch information
mihe committed Dec 13, 2022
1 parent 0d926a7 commit d48c16e
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 0 deletions.
15 changes: 15 additions & 0 deletions binding_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -1192,6 +1192,8 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
if is_singleton:
result.append(f"\tstatic {class_name} *get_singleton();")
result.append("")
result.append(f"\t~{class_name}();")
result.append("")

if "methods" in class_api:
for method in class_api["methods"]:
Expand Down Expand Up @@ -1314,6 +1316,8 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append("")

if is_singleton:
result.append(f"static bool {class_name}_singleton_destroyed = false;")
result.append("")
result.append(f"{class_name} *{class_name}::get_singleton() {{")
result.append(f"\tconst StringName __class_name = {class_name}::get_class_static();")
result.append(
Expand All @@ -1325,9 +1329,20 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
result.append(
f"\tstatic {class_name} *singleton = reinterpret_cast<{class_name} *>(internal::gde_interface->object_get_instance_binding(singleton_obj, internal::token, &{class_name}::___binding_callbacks));"
)
result.append(f"\tstatic struct {class_name}_BindingCleanup {{")
result.append(f"\t\t~{class_name}_BindingCleanup() {{")
result.append(f"\t\t\tif (!{class_name}_singleton_destroyed) {{")
result.append("\t\t\t\tinternal::gde_interface->object_clear_instance_binding(singleton_obj, internal::token);")
result.append("\t\t\t}")
result.append("\t\t}")
result.append("\t} binding_cleanup;")
result.append("\treturn singleton;")
result.append("}")
result.append("")
result.append(f"{class_name}::~{class_name}() {{")
result.append(f"\t{class_name}_singleton_destroyed = true;")
result.append("}")
result.append("")

if "methods" in class_api:
for method in class_api["methods"]:
Expand Down
1 change: 1 addition & 0 deletions godot-headers/godot/gdextension_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -544,6 +544,7 @@ typedef struct {

void *(*object_get_instance_binding)(GDExtensionObjectPtr p_o, void *p_token, const GDExtensionInstanceBindingCallbacks *p_callbacks);
void (*object_set_instance_binding)(GDExtensionObjectPtr p_o, void *p_token, void *p_binding, const GDExtensionInstanceBindingCallbacks *p_callbacks);
void (*object_clear_instance_binding)(GDExtensionObjectPtr p_o, void *p_token);

void (*object_set_instance)(GDExtensionObjectPtr p_o, GDExtensionConstStringNamePtr p_classname, GDExtensionClassInstancePtr p_instance); /* p_classname should be a registered extension class and should extend the p_o object's class. */

Expand Down

0 comments on commit d48c16e

Please sign in to comment.