summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRĂ©mi Verschelde <remi@verschelde.fr>2023-02-20 22:36:07 +0100
committerGitHub <noreply@github.com>2023-02-20 22:36:07 +0100
commit0851debf4500de68d5ee5c40e3e942c47c70214e (patch)
treee8e0e978277f15e69a430281a3cd9a6047c03b62
parente693a3debbe685f3632f1e420ac02a56ce26705d (diff)
parentc9e49c487da86883044c5d27b79bcf3a26802765 (diff)
Merge pull request #73639 from vnen/gdscript-limit-completion-recursion-depth
GDScript: Limit recursion depth for completion functions
-rw-r--r--modules/gdscript/gdscript_editor.cpp39
1 files changed, 39 insertions, 0 deletions
diff --git a/modules/gdscript/gdscript_editor.cpp b/modules/gdscript/gdscript_editor.cpp
index f79ba40e71..63dfd4d27c 100644
--- a/modules/gdscript/gdscript_editor.cpp
+++ b/modules/gdscript/gdscript_editor.cpp
@@ -1353,6 +1353,21 @@ static GDScriptCompletionIdentifier _type_from_property(const PropertyInfo &p_pr
return ci;
}
+#define MAX_COMPLETION_RECURSION 100
+struct RecursionCheck {
+ int *counter;
+ _FORCE_INLINE_ bool check() {
+ return (*counter) > MAX_COMPLETION_RECURSION;
+ }
+ RecursionCheck(int *p_counter) :
+ counter(p_counter) {
+ (*counter)++;
+ }
+ ~RecursionCheck() {
+ (*counter)--;
+ }
+};
+
static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type);
@@ -1385,6 +1400,12 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
return false;
}
+ static int recursion_depth = 0;
+ RecursionCheck recursion(&recursion_depth);
+ if (unlikely(recursion.check())) {
+ ERR_FAIL_V_MSG(false, "Reached recursion limit while trying to guess type.");
+ }
+
if (p_expression->is_constant) {
// Already has a value, so just use that.
r_type = _type_from_variant(p_expression->reduced_value);
@@ -1855,6 +1876,12 @@ static bool _guess_expression_type(GDScriptParser::CompletionContext &p_context,
}
static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
+ static int recursion_depth = 0;
+ RecursionCheck recursion(&recursion_depth);
+ if (unlikely(recursion.check())) {
+ ERR_FAIL_V_MSG(false, "Reached recursion limit while trying to guess type.");
+ }
+
// Look in blocks first.
int last_assign_line = -1;
const GDScriptParser::ExpressionNode *last_assigned_expression = nullptr;
@@ -2072,6 +2099,12 @@ static bool _guess_identifier_type(GDScriptParser::CompletionContext &p_context,
}
static bool _guess_identifier_type_from_base(GDScriptParser::CompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
+ static int recursion_depth = 0;
+ RecursionCheck recursion(&recursion_depth);
+ if (unlikely(recursion.check())) {
+ ERR_FAIL_V_MSG(false, "Reached recursion limit while trying to guess type.");
+ }
+
GDScriptParser::DataType base_type = p_base.type;
bool is_static = base_type.is_meta_type;
while (base_type.is_set()) {
@@ -2285,6 +2318,12 @@ static void _find_last_return_in_block(GDScriptParser::CompletionContext &p_cont
}
static bool _guess_method_return_type_from_base(GDScriptParser::CompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type) {
+ static int recursion_depth = 0;
+ RecursionCheck recursion(&recursion_depth);
+ if (unlikely(recursion.check())) {
+ ERR_FAIL_V_MSG(false, "Reached recursion limit while trying to guess type.");
+ }
+
GDScriptParser::DataType base_type = p_base.type;
bool is_static = base_type.is_meta_type;