Răsfoiți Sursa

Make Callable not crash on call when the object has been freed

Also add a GDScript test for this case.
George Marques 4 ani în urmă
părinte
comite
ea44744e2d

+ 9 - 0
core/variant/callable.cpp

@@ -50,6 +50,15 @@ void Callable::call(const Variant **p_arguments, int p_argcount, Variant &r_retu
 		custom->call(p_arguments, p_argcount, r_return_value, r_call_error);
 	} else {
 		Object *obj = ObjectDB::get_instance(ObjectID(object));
+#ifdef DEBUG_ENABLED
+		if (!obj) {
+			r_call_error.error = CallError::CALL_ERROR_INSTANCE_IS_NULL;
+			r_call_error.argument = 0;
+			r_call_error.expected = 0;
+			r_return_value = Variant();
+			return;
+		}
+#endif
 		r_return_value = obj->call(method, p_arguments, p_argcount, r_call_error);
 	}
 }

+ 5 - 0
modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.gd

@@ -0,0 +1,5 @@
+func test():
+	var node := Node.new()
+	var inside_tree = node.is_inside_tree
+	node.free()
+	inside_tree.call()

+ 6 - 0
modules/gdscript/tests/scripts/runtime/errors/callable_call_after_free_object.out

@@ -0,0 +1,6 @@
+GDTEST_RUNTIME_ERROR
+>> SCRIPT ERROR
+>> on function: test()
+>> runtime/errors/callable_call_after_free_object.gd
+>> 5
+>> Attempt to call function 'null::is_inside_tree (Callable)' on a null instance.