From aaad674f389eba6e1db03eeb76cd55e6b0af5833 Mon Sep 17 00:00:00 2001 From: taoxin <1015954373@qq.com> Date: Mon, 24 Aug 2026 10:31:56 +0800 Subject: [PATCH] fix(lua): consume escaped short-string newlines --- gitnexus/test/unit/parser-loader-abi.test.ts | 19 +++++++++++++++++++ gitnexus/vendor/tree-sitter-lua/src/scanner.c | 16 +++++++++++++--- 2 files changed, 32 insertions(+), 3 deletions(-) diff --git a/gitnexus/test/unit/parser-loader-abi.test.ts b/gitnexus/test/unit/parser-loader-abi.test.ts index f915c9677..5436630f8 100644 --- a/gitnexus/test/unit/parser-loader-abi.test.ts +++ b/gitnexus/test/unit/parser-loader-abi.test.ts @@ -193,4 +193,23 @@ describe('parser-loader ABI load-smoke (#1922)', () => { expect(tree.rootNode.hasError).toBe(false); } }); + + it('accepts a real newline escaped inside a short string', () => { + let grammar: unknown; + try { + grammar = getLanguageGrammar(SupportedLanguages.Lua); + } catch (err) { + expect(err).toBeInstanceOf(Error); + return; + } + + const parser = new Parser(); + parser.setLanguage(grammar as Parameters[0]); + const snippet = String.raw`local value = "line\ +continued" +`; + const tree = parser.parse(snippet); + expect(tree.rootNode.type).toBe('chunk'); + expect(tree.rootNode.hasError).toBe(false); + }); }); diff --git a/gitnexus/vendor/tree-sitter-lua/src/scanner.c b/gitnexus/vendor/tree-sitter-lua/src/scanner.c index 644098cea..898b31065 100644 --- a/gitnexus/vendor/tree-sitter-lua/src/scanner.c +++ b/gitnexus/vendor/tree-sitter-lua/src/scanner.c @@ -171,10 +171,20 @@ bool tree_sitter_lua_external_scanner_scan(void *payload, TSLexer *lexer, const // consume any character till a short string's end, new line or eof do { - // consume any character after a backslash, unless it's a new line or eof - if (consume_if(lexer, '\\') && (lexer->lookahead == '\n' || lexer->eof(lexer))) + // A backslash escapes the following character. Lua also permits a + // backslash followed by a real newline to continue a short string; + // consume that newline so the scanner does not remain stuck at it. + if (consume_if(lexer, '\\')) { - break; + if (lexer->lookahead == '\n') + { + consume(lexer); + continue; + } + if (lexer->eof(lexer)) + { + break; + } } consume(lexer);