Skip to content

Commit

Permalink
Fix use-after-free at shutdown, sync API files
Browse files Browse the repository at this point in the history
  • Loading branch information
mihe committed Nov 18, 2022
1 parent 6c2f919 commit 84565e4
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 @@ -1186,6 +1186,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 @@ -1308,6 +1310,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 @@ -1319,9 +1323,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::gdn_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::gdn_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/gdnative_interface.h
Original file line number Diff line number Diff line change
Expand Up @@ -541,6 +541,7 @@ typedef struct {

void *(*object_get_instance_binding)(GDNativeObjectPtr p_o, void *p_token, const GDNativeInstanceBindingCallbacks *p_callbacks);
void (*object_set_instance_binding)(GDNativeObjectPtr p_o, void *p_token, void *p_binding, const GDNativeInstanceBindingCallbacks *p_callbacks);
void (*object_clear_instance_binding)(GDNativeObjectPtr p_o, void *p_token);

void (*object_set_instance)(GDNativeObjectPtr p_o, const GDNativeStringNamePtr 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 84565e4

Please sign in to comment.