Merge pull request #73639 from vnen/gdscript-limit-completion-recursion-depth

GDScript: Limit recursion depth for completion functions
This commit is contained in:
Rémi Verschelde 2023-02-20 22:36:07 +01:00 committed by GitHub
commit 0851debf45
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -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;