浏览代码

Merge pull request #25715 from hpvb/fix-25598

Add a maximum recusion depth to _guess_expression_type
Rémi Verschelde 6 年之前
父节点
当前提交
fd60724c3d
共有 1 个文件被更改,包括 18 次插入9 次删除
  1. 18 9
      modules/gdscript/gdscript_editor.cpp

+ 18 - 9
modules/gdscript/gdscript_editor.cpp

@@ -479,12 +479,15 @@ struct GDScriptCompletionContext {
 	Object *base;
 	Object *base;
 	String base_path;
 	String base_path;
 	int line;
 	int line;
+	uint32_t depth;
 
 
 	GDScriptCompletionContext() :
 	GDScriptCompletionContext() :
 			_class(NULL),
 			_class(NULL),
 			function(NULL),
 			function(NULL),
 			block(NULL),
 			block(NULL),
-			base(NULL) {}
+			base(NULL),
+			line(0),
+			depth(0) {}
 };
 };
 
 
 struct GDScriptCompletionIdentifier {
 struct GDScriptCompletionIdentifier {
@@ -634,12 +637,18 @@ static GDScriptCompletionIdentifier _type_from_gdtype(const GDScriptDataType &p_
 	return ci;
 	return ci;
 }
 }
 
 
-static bool _guess_identifier_type(const GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
-static bool _guess_identifier_type_from_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
-static bool _guess_method_return_type_from_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type);
+static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
+static bool _guess_identifier_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type);
+static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type);
 
 
-static bool _guess_expression_type(const GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_expression, GDScriptCompletionIdentifier &r_type) {
+static bool _guess_expression_type(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_expression, GDScriptCompletionIdentifier &r_type) {
 	bool found = false;
 	bool found = false;
+
+	if (++p_context.depth > 100) {
+		print_error("Maximum _guess_expression_type depth limit reached. Please file a bugreport.");
+		return false;
+	}
+
 	switch (p_expression->type) {
 	switch (p_expression->type) {
 		case GDScriptParser::Node::TYPE_CONSTANT: {
 		case GDScriptParser::Node::TYPE_CONSTANT: {
 			const GDScriptParser::ConstantNode *cn = static_cast<const GDScriptParser::ConstantNode *>(p_expression);
 			const GDScriptParser::ConstantNode *cn = static_cast<const GDScriptParser::ConstantNode *>(p_expression);
@@ -1128,7 +1137,7 @@ static bool _guess_expression_type(const GDScriptCompletionContext &p_context, c
 	return found;
 	return found;
 }
 }
 
 
-static bool _guess_identifier_type(const GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
+static bool _guess_identifier_type(GDScriptCompletionContext &p_context, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
 
 
 	// Look in blocks first
 	// Look in blocks first
 	const GDScriptParser::BlockNode *blk = p_context.block;
 	const GDScriptParser::BlockNode *blk = p_context.block;
@@ -1358,7 +1367,7 @@ static bool _guess_identifier_type(const GDScriptCompletionContext &p_context, c
 	return false;
 	return false;
 }
 }
 
 
-static bool _guess_identifier_type_from_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
+static bool _guess_identifier_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_identifier, GDScriptCompletionIdentifier &r_type) {
 	GDScriptParser::DataType base_type = p_base.type;
 	GDScriptParser::DataType base_type = p_base.type;
 	bool _static = base_type.is_meta_type;
 	bool _static = base_type.is_meta_type;
 	while (base_type.has_type) {
 	while (base_type.has_type) {
@@ -1547,7 +1556,7 @@ static bool _find_last_return_in_block(const GDScriptCompletionContext &p_contex
 	return false;
 	return false;
 }
 }
 
 
-static bool _guess_method_return_type_from_base(const GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type) {
+static bool _guess_method_return_type_from_base(GDScriptCompletionContext &p_context, const GDScriptCompletionIdentifier &p_base, const StringName &p_method, GDScriptCompletionIdentifier &r_type) {
 	GDScriptParser::DataType base_type = p_base.type;
 	GDScriptParser::DataType base_type = p_base.type;
 	bool _static = base_type.is_meta_type;
 	bool _static = base_type.is_meta_type;
 
 
@@ -2312,7 +2321,7 @@ static void _find_call_arguments(const GDScriptCompletionContext &p_context, con
 	}
 	}
 }
 }
 
 
-static void _find_call_arguments(const GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Set<String> &r_result, bool &r_forced, String &r_arghint) {
+static void _find_call_arguments(GDScriptCompletionContext &p_context, const GDScriptParser::Node *p_node, int p_argidx, Set<String> &r_result, bool &r_forced, String &r_arghint) {
 
 
 	if (!p_node || p_node->type != GDScriptParser::Node::TYPE_OPERATOR) {
 	if (!p_node || p_node->type != GDScriptParser::Node::TYPE_OPERATOR) {
 		return;
 		return;