diff options
author | Christian Clason <c.clason@uni-graz.at> | 2023-01-26 09:42:23 +0100 |
---|---|---|
committer | Christian Clason <c.clason@uni-graz.at> | 2023-01-28 11:28:52 +0100 |
commit | c032e83b22994332dd8769ef34cb817906a63cac (patch) | |
tree | 5c2d8c7131e07c1a6597c496d018e60e706e4cda | |
parent | b4c4c232ba6fe3df5c6f12faff4405a16e4d40df (diff) | |
download | rneovim-c032e83b22994332dd8769ef34cb817906a63cac.tar.gz rneovim-c032e83b22994332dd8769ef34cb817906a63cac.tar.bz2 rneovim-c032e83b22994332dd8769ef34cb817906a63cac.zip |
fix(treesitter): validate language name
Problem: Some injections (like markdown) allow specifying arbitrary
language names for code blocks, which may be lead to errors when
looking for a corresponding parser in runtime path.
Solution: Validate that the language name only contains alphanumeric
characters and `_` (e.g., for `c_sharp`) and error otherwise.
-rw-r--r-- | runtime/doc/treesitter.txt | 1 | ||||
-rw-r--r-- | runtime/lua/vim/treesitter/language.lua | 12 | ||||
-rw-r--r-- | test/functional/treesitter/language_spec.lua | 5 |
3 files changed, 15 insertions, 3 deletions
diff --git a/runtime/doc/treesitter.txt b/runtime/doc/treesitter.txt index 917863eef8..9bfdc0b94e 100644 --- a/runtime/doc/treesitter.txt +++ b/runtime/doc/treesitter.txt @@ -684,6 +684,7 @@ require_language({lang}, {path}, {silent}, {symbol_name}) Parameters: ~ • {lang} (string) Language the parser should parse + (alphanumerical and `_` only) • {path} (string|nil) Optional path the parser is located at • {silent} (boolean|nil) Don't throw an error if language not found diff --git a/runtime/lua/vim/treesitter/language.lua b/runtime/lua/vim/treesitter/language.lua index c92d63b8c4..8634e53b7b 100644 --- a/runtime/lua/vim/treesitter/language.lua +++ b/runtime/lua/vim/treesitter/language.lua @@ -6,7 +6,7 @@ local M = {} --- --- Parsers are searched in the `parser` runtime directory, or the provided {path} --- ----@param lang string Language the parser should parse +---@param lang string Language the parser should parse (alphanumerical and `_` only) ---@param path (string|nil) Optional path the parser is located at ---@param silent (boolean|nil) Don't throw an error if language not found ---@param symbol_name (string|nil) Internal symbol name for the language to load @@ -16,13 +16,19 @@ function M.require_language(lang, path, silent, symbol_name) return true end if path == nil then - local fname = 'parser/' .. vim.fn.fnameescape(lang) .. '.*' + if not (lang and lang:match('[%w_]+') == lang) then + if silent then + return false + end + error("'" .. lang .. "' is not a valid language name") + end + + local fname = 'parser/' .. lang .. '.*' local paths = a.nvim_get_runtime_file(fname, false) if #paths == 0 then if silent then return false end - error("no parser for '" .. lang .. "' language, see :help treesitter-parsers") end path = paths[1] diff --git a/test/functional/treesitter/language_spec.lua b/test/functional/treesitter/language_spec.lua index f95b05a1cc..df45c9b384 100644 --- a/test/functional/treesitter/language_spec.lua +++ b/test/functional/treesitter/language_spec.lua @@ -31,6 +31,11 @@ describe('treesitter language API', function() pcall_err(exec_lua, 'vim.treesitter.require_language("c", nil, false, "borklang")')) end) + it('shows error for invalid language name', function() + eq(".../language.lua:0: '/foo/' is not a valid language name", + pcall_err(exec_lua, 'vim.treesitter.require_language("/foo/", nil, false)')) + end) + it('inspects language', function() local keys, fields, symbols = unpack(exec_lua([[ local lang = vim.treesitter.inspect_language('c') |