From 144e0856a49e2f50e47526f51b79940bc86fd733 Mon Sep 17 00:00:00 2001 From: Yuri Roubinsky Date: Wed, 11 Aug 2021 09:38:38 +0300 Subject: [PATCH] Fix shader crash when using varying array in fragment->light context (cherry picked from commit fead1595f9c37105fe050ca89218e387ebe85dea) --- servers/visual/shader_language.cpp | 41 ++++++++++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/servers/visual/shader_language.cpp b/servers/visual/shader_language.cpp index 85e4ff4daca..2b1312d6d1a 100644 --- a/servers/visual/shader_language.cpp +++ b/servers/visual/shader_language.cpp @@ -3520,9 +3520,16 @@ ShaderLanguage::Node *ShaderLanguage::_parse_expression(BlockNode *p_block, cons if (ident_type == IDENTIFIER_VARYING) { TkPos prev_pos = _get_tkpos(); Token next_token = _get_token(); - _set_tkpos(prev_pos); - String error; + // An array of varyings. + if (next_token.type == TK_BRACKET_OPEN) { + _get_token(); // Pass constant. + _get_token(); // Pass TK_BRACKET_CLOSE. + next_token = _get_token(); + } + _set_tkpos(prev_pos); + + String error; if (is_token_operator_assign(next_token.type)) { if (!_validate_varying_assign(shader->varyings[identifier], &error)) { _set_error(error); @@ -5788,6 +5795,7 @@ Error ShaderLanguage::_parse_shader(const Map &p_funct DataInterpolation interpolation = INTERPOLATION_SMOOTH; DataType type; StringName name; + int array_size = 0; tk = _get_token(); if (is_token_interpolation(tk.type)) { @@ -5818,6 +5826,30 @@ Error ShaderLanguage::_parse_shader(const Map &p_funct } tk = _get_token(); + + if (tk.type == TK_BRACKET_OPEN) { + if (uniform) { + _set_error(vformat("Uniform arrays are not yet implemented!")); + return ERR_PARSE_ERROR; + } + tk = _get_token(); + + if (tk.type == TK_INT_CONSTANT && tk.constant > 0) { + array_size = (int)tk.constant; + + tk = _get_token(); + if (tk.type == TK_BRACKET_CLOSE) { + tk = _get_token(); + } else { + _set_error("Expected ']'"); + return ERR_PARSE_ERROR; + } + } else { + _set_error("Expected integer constant > 0"); + return ERR_PARSE_ERROR; + } + } + if (tk.type != TK_IDENTIFIER) { _set_error("Expected identifier!"); return ERR_PARSE_ERROR; @@ -6002,6 +6034,7 @@ Error ShaderLanguage::_parse_shader(const Map &p_funct varying.precision = precision; varying.interpolation = interpolation; varying.tkpos = name_pos; + varying.array_size = array_size; tk = _get_token(); if (tk.type != TK_SEMICOLON && tk.type != TK_BRACKET_OPEN) { @@ -6010,6 +6043,10 @@ Error ShaderLanguage::_parse_shader(const Map &p_funct } if (tk.type == TK_BRACKET_OPEN) { + if (array_size > 0) { + _set_error("Array size is already defined!"); + return ERR_PARSE_ERROR; + } tk = _get_token(); if (tk.type == TK_INT_CONSTANT && tk.constant > 0) { varying.array_size = (int)tk.constant;