diff options
author | RĂ©mi Verschelde <remi@verschelde.fr> | 2023-02-20 22:36:07 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-02-20 22:36:07 +0100 |
commit | 0851debf4500de68d5ee5c40e3e942c47c70214e (patch) | |
tree | e8e0e978277f15e69a430281a3cd9a6047c03b62 | |
parent | e693a3debbe685f3632f1e420ac02a56ce26705d (diff) | |
parent | c9e49c487da86883044c5d27b79bcf3a26802765 (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.cpp | 39 |
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; |