fix(api): nvim_cmd{cmd="win_getid"} parsed as :winsize #24181

Problem:
`:lua vim.cmd.win_getid(30,10)` is interpreted as `:win[size] 30 10`.
User intention was to call `vim.fn.win_getid(30,10)`.

Solution:
Check that the `cmd` actually matches the resolved command.
This commit is contained in:
Justin M. Keyes 2023-06-28 04:51:55 -07:00 committed by GitHub
parent 42f9573e5d
commit e0453d7f57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 15 additions and 9 deletions

View File

@ -208,15 +208,11 @@ To debug the main process, you can debug the nvim binary with the `--headless`
flag which does not launch the TUI and will allow you to set breakpoints in code flag which does not launch the TUI and will allow you to set breakpoints in code
not related to TUI rendering like so: not related to TUI rendering like so:
``` lldb -- ./build/bin/nvim --headless --listen ~/.cache/nvim/debug-server.pipe
lldb -- ./build/bin/nvim --headless --listen ~/.cache/nvim/debug-server.pipe
```
You can then attach to the headless process to interact with the editor like so: You can then attach to the headless process to interact with the editor like so:
``` ./build/bin/nvim --remote-ui --server ~/.cache/nvim/debug-server.pipe
./build/bin/nvim --remote-ui --server ~/.cache/nvim/debug-server.pipe
```
Conversely for debugging TUI rendering, you can start a headless process and Conversely for debugging TUI rendering, you can start a headless process and
debug the remote-ui process multiple times without losing editor state. debug the remote-ui process multiple times without losing editor state.

View File

@ -393,6 +393,12 @@ String nvim_cmd(uint64_t channel_id, Dict(cmd) *cmd, Dict(cmd_opts) *opts, Error
VALIDATE(!is_cmd_ni(ea.cmdidx), "Command not implemented: %s", cmdname, { VALIDATE(!is_cmd_ni(ea.cmdidx), "Command not implemented: %s", cmdname, {
goto end; goto end;
}); });
const char *fullname = IS_USER_CMDIDX(ea.cmdidx)
? get_user_command_name(ea.useridx, ea.cmdidx)
: get_command_name(NULL, ea.cmdidx);
VALIDATE(strncmp(fullname, cmdname, strlen(cmdname)) == 0, "Invalid command: \"%s\"", cmdname, {
goto end;
});
// Get the command flags so that we can know what type of arguments the command uses. // Get the command flags so that we can know what type of arguments the command uses.
// Not required for a user command since `find_ex_command` already deals with it in that case. // Not required for a user command since `find_ex_command` already deals with it in that case.

View File

@ -335,8 +335,7 @@ describe('API', function()
nvim('command', 'edit '..fname) nvim('command', 'edit '..fname)
nvim('command', 'normal itesting\napi') nvim('command', 'normal itesting\napi')
nvim('command', 'w') nvim('command', 'w')
local f = io.open(fname) local f = assert(io.open(fname))
ok(f ~= nil)
if is_os('win') then if is_os('win') then
eq('testing\r\napi\r\n', f:read('*a')) eq('testing\r\napi\r\n', f:read('*a'))
else else
@ -3950,7 +3949,7 @@ describe('API', function()
} }
}, meths.parse_cmd('MyCommand test it', {})) }, meths.parse_cmd('MyCommand test it', {}))
end) end)
it('errors for invalid command', function() it('validates command', function()
eq('Error while parsing command line', pcall_err(meths.parse_cmd, '', {})) eq('Error while parsing command line', pcall_err(meths.parse_cmd, '', {}))
eq('Error while parsing command line', pcall_err(meths.parse_cmd, '" foo', {})) eq('Error while parsing command line', pcall_err(meths.parse_cmd, '" foo', {}))
eq('Error while parsing command line: E492: Not an editor command: Fubar', eq('Error while parsing command line: E492: Not an editor command: Fubar',
@ -4097,6 +4096,11 @@ describe('API', function()
eq("Invalid 'reg': expected single character, got xx", eq("Invalid 'reg': expected single character, got xx",
pcall_err(meths.cmd, { cmd = "put", args = {}, reg = 'xx' }, {})) pcall_err(meths.cmd, { cmd = "put", args = {}, reg = 'xx' }, {}))
-- #20681
eq('Invalid command: "win_getid"', pcall_err(meths.cmd, { cmd = 'win_getid'}, {}))
eq('Invalid command: "echo "hi""', pcall_err(meths.cmd, { cmd = 'echo "hi"'}, {}))
eq('Invalid command: "win_getid"', pcall_err(exec_lua, [[return vim.cmd.win_getid{}]]))
-- Lua call allows empty {} for dict item. -- Lua call allows empty {} for dict item.
eq('', exec_lua([[return vim.cmd{ cmd = "set", args = {}, magic = {} }]])) eq('', exec_lua([[return vim.cmd{ cmd = "set", args = {}, magic = {} }]]))
eq('', exec_lua([[return vim.cmd{ cmd = "set", args = {}, mods = {} }]])) eq('', exec_lua([[return vim.cmd{ cmd = "set", args = {}, mods = {} }]]))