From d3a0761d038e2f01dfdaf89f8c6029c8c965da64 Mon Sep 17 00:00:00 2001 From: Andrew Price Date: Thu, 6 Nov 2025 05:01:19 +0000 Subject: [PATCH] Fix consume_line_continuations() skipping characters This function increments the code index by 2 when a line continuation is found, additional to the loop increment, so it skips over the next character following a line continuation. In shader code like #define FUN_FUN(n)\ void fun1() { return;\ }\ void fun2() { return; } FUN_FUN(1.0) the first } will visibly get skipped, causing an error. The 'v' in 'void' will also get missed, but as the next 'o' is enough to decide to end the loop, that is less obvious. Simplify consume_line_continuations() to remove the unnecessary offset parameter and the extra loop index variable, and increment index the right amount. --- servers/rendering/shader_preprocessor.cpp | 37 +++++++++++------------ servers/rendering/shader_preprocessor.h | 2 +- 2 files changed, 19 insertions(+), 20 deletions(-) diff --git a/servers/rendering/shader_preprocessor.cpp b/servers/rendering/shader_preprocessor.cpp index ee34504b79b8..9876ca0fc262 100644 --- a/servers/rendering/shader_preprocessor.cpp +++ b/servers/rendering/shader_preprocessor.cpp @@ -78,24 +78,23 @@ char32_t ShaderPreprocessor::Tokenizer::peek() { return 0; } -int ShaderPreprocessor::Tokenizer::consume_line_continuations(int p_offset) { +int ShaderPreprocessor::Tokenizer::consume_line_continuations() { int skips = 0; - for (int i = index + p_offset; i < size; i++) { - char32_t c = code[i]; - if (c == '\\') { - if (i + 1 < size && code[i + 1] == '\n') { - // This line ends with "\" and "\n" continuation. - add_generated(Token('\n', line)); - line++; - skips++; - - i = i + 2; - index = i; - } else { - break; + for (; index < size; index++) { + char32_t c = code[index]; + if (c != '\\') { + if (is_whitespace(c)) { + continue; } - } else if (!is_whitespace(c)) { + break; + } + if (index + 1 < size && code[index + 1] == '\n') { + add_generated(Token('\n', line)); + line++; + skips++; + index++; + } else { break; } } @@ -106,11 +105,11 @@ LocalVector ShaderPreprocessor::Tokenizer::advance(ch LocalVector tokens; while (index < size) { - char32_t c = code[index++]; - if (c == '\\' && consume_line_continuations(-1) > 0) { + char32_t c = code[index]; + if (c == '\\' && consume_line_continuations() > 0) { continue; } - + index++; if (c == '\n') { add_generated(ShaderPreprocessor::Token('\n', line)); line++; @@ -145,7 +144,7 @@ String ShaderPreprocessor::Tokenizer::get_identifier(bool *r_is_cursor, bool p_s while (true) { char32_t c = peek(); - if (c == '\\' && consume_line_continuations(0) > 0) { + if (c == '\\' && consume_line_continuations() > 0) { continue; } diff --git a/servers/rendering/shader_preprocessor.h b/servers/rendering/shader_preprocessor.h index 3b386af68797..2e41f882a9c1 100644 --- a/servers/rendering/shader_preprocessor.h +++ b/servers/rendering/shader_preprocessor.h @@ -89,7 +89,7 @@ class ShaderPreprocessor { int get_line() const; int get_index() const; char32_t peek(); - int consume_line_continuations(int p_offset); + int consume_line_continuations(); void get_and_clear_generated(LocalVector *r_out); void backtrack(char32_t p_what);