Browse Source

Forbid varyings from assigning in custom functions to prevent crashes

Yuri Roubinsky 4 years ago
parent
commit
39c06604cd
1 changed files with 13 additions and 2 deletions
  1. 13 2
      servers/rendering/shader_language.cpp

+ 13 - 2
servers/rendering/shader_language.cpp

@@ -2436,6 +2436,10 @@ bool ShaderLanguage::_validate_function_call(BlockNode *p_block, const FunctionI
 										if (shader->uniforms.has(varname)) {
 										if (shader->uniforms.has(varname)) {
 											fail = true;
 											fail = true;
 										} else {
 										} else {
+											if (shader->varyings.has(varname)) {
+												_set_error(vformat("Varyings cannot be passed for '%s' parameter!", "out"));
+												return false;
+											}
 											if (p_function_info.built_ins.has(varname)) {
 											if (p_function_info.built_ins.has(varname)) {
 												BuiltInInfo info = p_function_info.built_ins[varname];
 												BuiltInInfo info = p_function_info.built_ins[varname];
 												if (info.constant) {
 												if (info.constant) {
@@ -3308,8 +3312,8 @@ bool ShaderLanguage::_is_operator_assign(Operator p_op) const {
 }
 }
 
 
 bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message) {
 bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, String *r_message) {
-	if (current_function == String("light")) {
-		*r_message = RTR("Varying may not be assigned in the 'light' function.");
+	if (current_function != String("vertex") && current_function != String("fragment")) {
+		*r_message = vformat(RTR("Varying may not be assigned in the '%s' function."), current_function);
 		return false;
 		return false;
 	}
 	}
 	switch (p_varying.stage) {
 	switch (p_varying.stage) {
@@ -3320,12 +3324,15 @@ bool ShaderLanguage::_validate_varying_assign(ShaderNode::Varying &p_varying, St
 				p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT;
 				p_varying.stage = ShaderNode::Varying::STAGE_FRAGMENT;
 			}
 			}
 			break;
 			break;
+		case ShaderNode::Varying::STAGE_VERTEX_TO_FRAGMENT:
+		case ShaderNode::Varying::STAGE_VERTEX_TO_LIGHT:
 		case ShaderNode::Varying::STAGE_VERTEX:
 		case ShaderNode::Varying::STAGE_VERTEX:
 			if (current_function == varying_function_names.fragment) {
 			if (current_function == varying_function_names.fragment) {
 				*r_message = RTR("Varyings which assigned in 'vertex' function may not be reassigned in 'fragment' or 'light'.");
 				*r_message = RTR("Varyings which assigned in 'vertex' function may not be reassigned in 'fragment' or 'light'.");
 				return false;
 				return false;
 			}
 			}
 			break;
 			break;
+		case ShaderNode::Varying::STAGE_FRAGMENT_TO_LIGHT:
 		case ShaderNode::Varying::STAGE_FRAGMENT:
 		case ShaderNode::Varying::STAGE_FRAGMENT:
 			if (current_function == varying_function_names.vertex) {
 			if (current_function == varying_function_names.vertex) {
 				*r_message = RTR("Varyings which assigned in 'fragment' function may not be reassigned in 'vertex' or 'light'.");
 				*r_message = RTR("Varyings which assigned in 'fragment' function may not be reassigned in 'vertex' or 'light'.");
@@ -4116,6 +4123,10 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons
 												} else if (shader->uniforms.has(varname)) {
 												} else if (shader->uniforms.has(varname)) {
 													error = true;
 													error = true;
 												} else {
 												} else {
+													if (shader->varyings.has(varname)) {
+														_set_error(vformat("Varyings cannot be passed for '%s' parameter!", _get_qualifier_str(call_function->arguments[i].qualifier)));
+														return nullptr;
+													}
 													if (p_function_info.built_ins.has(varname)) {
 													if (p_function_info.built_ins.has(varname)) {
 														BuiltInInfo info = p_function_info.built_ins[varname];
 														BuiltInInfo info = p_function_info.built_ins[varname];
 														if (info.constant) {
 														if (info.constant) {