From f9080b24c4f60c3772db2b6e713ea5a6a3b52f1e Mon Sep 17 00:00:00 2001 From: Lewis Russell Date: Thu, 27 Jan 2022 09:42:59 +0000 Subject: [PATCH] fix(ts): escape lang when loading parsers (#16668) When trying to load a language parser, escape the value of the language. With language injection, the language might be picked up from the buffer. If this value is erroneous it can cause `nvim_get_runtime_file` to hard error. E.g., the markdown expression `~~~{` will extract '{' as a language and then try to get the parser using `parser/{*` as the pattern. --- runtime/lua/vim/treesitter/language.lua | 2 +- test/functional/treesitter/parser_spec.lua | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/runtime/lua/vim/treesitter/language.lua b/runtime/lua/vim/treesitter/language.lua index 6f347ff25f..8b106108df 100644 --- a/runtime/lua/vim/treesitter/language.lua +++ b/runtime/lua/vim/treesitter/language.lua @@ -14,7 +14,7 @@ function M.require_language(lang, path, silent) return true end if path == nil then - local fname = 'parser/' .. lang .. '.*' + local fname = 'parser/' .. vim.fn.fnameescape(lang) .. '.*' local paths = a.nvim_get_runtime_file(fname, false) if #paths == 0 then if silent then diff --git a/test/functional/treesitter/parser_spec.lua b/test/functional/treesitter/parser_spec.lua index 44a7f00d8b..396fe5feab 100644 --- a/test/functional/treesitter/parser_spec.lua +++ b/test/functional/treesitter/parser_spec.lua @@ -666,6 +666,21 @@ int x = INT_MAX; -- READ_STRING_OK(x, y) (char_u *)read_string((x), (size_t)(y)) }, get_ranges()) end) + + it("should not inject bad languages", function() + if helpers.pending_win32(pending) then return end + exec_lua([=[ + vim.treesitter.add_directive("inject-bad!", function(match, _, _, pred, metadata) + metadata.language = "{" + metadata.combined = true + metadata.content = pred[2] + end) + + parser = vim.treesitter.get_parser(0, "c", { + injections = { + c = "(preproc_function_def value: ((preproc_arg) @_a (#inject-bad! @_a)))"}}) + ]=]) + end) end) describe("when using the offset directive", function()