fix(lsp): handle nil bytes in strings

Problem:

The LSP omnifunc can insert nil bytes, which when read in other places
(like semantic token) could cause an error:

    semantic_tokens.lua:304: Vim:E976: Using a Blob as a String

Solution:

Use `#line` instead of `vim.fn.strlen(line)`. Both return UTF-8 bytes
but the latter can't handle nil bytes.

Completion candidates can currently insert nil bytes, if other parts of
Alternative fix to https://github.com/neovim/neovim/pull/30359

Note that https://github.com/neovim/neovim/pull/30315 will avoid the
insertion of nil bytes from the LSP omnifunc, but the change of this PR
can more easily be backported.

(cherry picked from commit 8512f669f0)
This commit is contained in:
Mathias Fussenegger
2024-09-13 19:57:04 +02:00
committed by github-actions[bot]
parent b020b66005
commit f3675337f0

View File

@ -155,7 +155,7 @@ end
---@param encoding string utf-8|utf-16|utf-32| defaults to utf-16 ---@param encoding string utf-8|utf-16|utf-32| defaults to utf-16
---@return integer byte (utf-8) index of `encoding` index `index` in `line` ---@return integer byte (utf-8) index of `encoding` index `index` in `line`
function M._str_byteindex_enc(line, index, encoding) function M._str_byteindex_enc(line, index, encoding)
local len = vim.fn.strlen(line) local len = #line
if index > len then if index > len then
-- LSP spec: if character > line length, default to the line length. -- LSP spec: if character > line length, default to the line length.
-- https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position -- https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#position
@ -168,7 +168,7 @@ function M._str_byteindex_enc(line, index, encoding)
if index then if index then
return index return index
else else
return #line return len
end end
elseif encoding == 'utf-16' then elseif encoding == 'utf-16' then
return vim.str_byteindex(line, index, true) return vim.str_byteindex(line, index, true)