fix(api): leak preview callback LuaRef in nvim_create_user_command #39357

Problem:
Invalid `nvim_create_user_command` calls can leak the
`preview` callback reference after Neovim has taken ownership of it.

1. build with {a,l}san
2. run:
    ```sh
    <path/to/nvim> --headless -u NONE --clean +'lua
    for i = 1, 100 do
      pcall(vim.api.nvim_create_user_command,
        "some very epic stuff" .. i,
        {}, -- NOTE: this is INVALID (not a function or string)
        { preview = function() end })
    end
    vim.cmd("qa!")
    ' +qa
    ```
3. see:
    ```
    100 lua references were leaked!
    ```

Solution:
Clear `preview_luaref` in `err:`.
This commit is contained in:
Barrett Ruth
2026-04-24 14:13:24 -04:00
committed by GitHub
parent 58aad59e1c
commit 393f687503
2 changed files with 22 additions and 1 deletions

View File

@@ -274,6 +274,25 @@ describe('nvim_create_user_command', function()
eq(42, api.nvim_eval('g:command_fired'))
end)
it('does not leak `preview` LuaRef on invalid `cmd`', function()
local released = exec_lua(function()
local weak = setmetatable({}, { __mode = 'v' })
for i = 1, 10 do
local cb = function() end
weak[i] = cb
pcall(vim.api.nvim_create_user_command, 'Bogus' .. i, {}, { preview = cb })
end
collectgarbage('collect')
collectgarbage('collect')
local n = 0
for _ in pairs(weak) do
n = n + 1
end
return n
end)
eq(0, released)
end)
it('works with Lua functions', function()
exec_lua [[
result = {}