From 10b00bc2eaa5d6e49ed68eb5eb832abfdeff5f1a Mon Sep 17 00:00:00 2001 From: Danil Alexeev Date: Fri, 22 Sep 2023 10:10:22 +0300 Subject: [PATCH] GDScript: Prevent constructing and inheriting engine singletons --- modules/gdscript/gdscript_analyzer.cpp | 10 ++++++++++ .../analyzer/errors/engine_singleton_instantiate.gd | 2 ++ .../analyzer/errors/engine_singleton_instantiate.out | 2 ++ .../scripts/analyzer/errors/extend_engine_singleton.gd | 6 ++++++ .../analyzer/errors/extend_engine_singleton.out | 2 ++ 5 files changed, 22 insertions(+) create mode 100644 modules/gdscript/tests/scripts/analyzer/errors/engine_singleton_instantiate.gd create mode 100644 modules/gdscript/tests/scripts/analyzer/errors/engine_singleton_instantiate.out create mode 100644 modules/gdscript/tests/scripts/analyzer/errors/extend_engine_singleton.gd create mode 100644 modules/gdscript/tests/scripts/analyzer/errors/extend_engine_singleton.out diff --git a/modules/gdscript/gdscript_analyzer.cpp b/modules/gdscript/gdscript_analyzer.cpp index 04c86d60a8c..92050154b59 100644 --- a/modules/gdscript/gdscript_analyzer.cpp +++ b/modules/gdscript/gdscript_analyzer.cpp @@ -459,6 +459,10 @@ Error GDScriptAnalyzer::resolve_class_inheritance(GDScriptParser::ClassNode *p_c } base = info_parser->get_parser()->head->get_datatype(); } else if (class_exists(name)) { + if (Engine::get_singleton()->has_singleton(name)) { + push_error(vformat(R"(Cannot inherit native class "%s" because it is an engine singleton.)", name), id); + return ERR_PARSE_ERROR; + } base.kind = GDScriptParser::DataType::NATIVE; base.native_type = name; } else { @@ -3203,6 +3207,12 @@ void GDScriptAnalyzer::reduce_call(GDScriptParser::CallNode *p_call, bool p_is_a bool is_constructor = (base_type.is_meta_type || (p_call->callee && p_call->callee->type == GDScriptParser::Node::IDENTIFIER)) && p_call->function_name == SNAME("new"); + if (is_constructor && Engine::get_singleton()->has_singleton(base_type.native_type)) { + push_error(vformat(R"(Cannot construct native class "%s" because it is an engine singleton.)", base_type.native_type), p_call); + p_call->set_datatype(call_type); + return; + } + if (get_function_signature(p_call, is_constructor, base_type, p_call->function_name, return_type, par_types, default_arg_count, method_flags)) { // If the method is implemented in the class hierarchy, the virtual flag will not be set for that MethodInfo and the search stops there. // Virtual check only possible for super() calls because class hierarchy is known. Node/Objects may have scripts attached we don't know of at compile-time. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/engine_singleton_instantiate.gd b/modules/gdscript/tests/scripts/analyzer/errors/engine_singleton_instantiate.gd new file mode 100644 index 00000000000..7e1efb8d1b4 --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/engine_singleton_instantiate.gd @@ -0,0 +1,2 @@ +func test(): + Time.new() diff --git a/modules/gdscript/tests/scripts/analyzer/errors/engine_singleton_instantiate.out b/modules/gdscript/tests/scripts/analyzer/errors/engine_singleton_instantiate.out new file mode 100644 index 00000000000..bc4875d908f --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/engine_singleton_instantiate.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot construct native class "Time" because it is an engine singleton. diff --git a/modules/gdscript/tests/scripts/analyzer/errors/extend_engine_singleton.gd b/modules/gdscript/tests/scripts/analyzer/errors/extend_engine_singleton.gd new file mode 100644 index 00000000000..a46b6d8658b --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/extend_engine_singleton.gd @@ -0,0 +1,6 @@ +# GH-82081 + +extends Time + +func test(): + pass diff --git a/modules/gdscript/tests/scripts/analyzer/errors/extend_engine_singleton.out b/modules/gdscript/tests/scripts/analyzer/errors/extend_engine_singleton.out new file mode 100644 index 00000000000..7c26dea56ed --- /dev/null +++ b/modules/gdscript/tests/scripts/analyzer/errors/extend_engine_singleton.out @@ -0,0 +1,2 @@ +GDTEST_ANALYZER_ERROR +Cannot inherit native class "Time" because it is an engine singleton.