diff options
author | ii14 <59243201+ii14@users.noreply.github.com> | 2022-12-05 19:59:04 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-05 11:59:04 -0700 |
commit | f3bf1fbf600050fde155e6a1a766b6f848012208 (patch) | |
tree | 4de99c04bf7d666ac15707e418468640c0946b1a | |
parent | 707df880545703bc6f4db1af6e46820becbcd911 (diff) | |
download | rneovim-f3bf1fbf600050fde155e6a1a766b6f848012208.tar.gz rneovim-f3bf1fbf600050fde155e6a1a766b6f848012208.tar.bz2 rneovim-f3bf1fbf600050fde155e6a1a766b6f848012208.zip |
fix(secure): crash when hitting escape in prompt (#21283)
- use pcall when calling vim.secure.read from C
- catch keyboard interrupts in vim.secure.read, rethrow other errors
- selecting "view" in prompt runs :view command
- simplify lua stack cleanup with lua_gettop and lua_settop
Co-authored-by: ii14 <ii14@users.noreply.github.com>
-rw-r--r-- | runtime/lua/vim/secure.lua | 25 | ||||
-rw-r--r-- | src/nvim/lua/executor.c | 19 | ||||
-rw-r--r-- | test/functional/lua/secure_spec.lua | 6 |
3 files changed, 24 insertions, 26 deletions
diff --git a/runtime/lua/vim/secure.lua b/runtime/lua/vim/secure.lua index 08b1ff871c..443b152273 100644 --- a/runtime/lua/vim/secure.lua +++ b/runtime/lua/vim/secure.lua @@ -80,34 +80,27 @@ function M.read(path) end -- File either does not exist in trust database or the hash does not match - local choice = vim.fn.confirm( + local ok, result = pcall( + vim.fn.confirm, string.format('%s is not trusted.', fullpath), '&ignore\n&view\n&deny\n&allow', 1 ) - if choice == 0 or choice == 1 then + if not ok and result ~= 'Keyboard interrupt' then + error(result) + elseif not ok or result == 0 or result == 1 then -- Cancelled or ignored return nil - elseif choice == 2 then + elseif result == 2 then -- View - vim.cmd('new') - local buf = vim.api.nvim_get_current_buf() - local lines = vim.split(string.gsub(contents, '\n$', ''), '\n') - vim.api.nvim_buf_set_lines(buf, 0, -1, false, lines) - vim.bo[buf].bufhidden = 'hide' - vim.bo[buf].buftype = 'nofile' - vim.bo[buf].swapfile = false - vim.bo[buf].modeline = false - vim.bo[buf].buflisted = false - vim.bo[buf].readonly = true - vim.bo[buf].modifiable = false + vim.cmd('sview ' .. fullpath) return nil - elseif choice == 3 then + elseif result == 3 then -- Deny trust[fullpath] = '!' contents = nil - elseif choice == 4 then + elseif result == 4 then -- Allow trust[fullpath] = hash end diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index 48ab2e3d70..1c8fe3e28e 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -2197,11 +2197,17 @@ plain: char *nlua_read_secure(const char *path) { lua_State *const lstate = global_lstate; + const int top = lua_gettop(lstate); + lua_getglobal(lstate, "vim"); lua_getfield(lstate, -1, "secure"); lua_getfield(lstate, -1, "read"); lua_pushstring(lstate, path); - lua_call(lstate, 1, 1); + if (nlua_pcall(lstate, 1, 1)) { + nlua_error(lstate, _("Error executing vim.secure.read: %.*s")); + lua_settop(lstate, top); + return NULL; + } size_t len = 0; const char *contents = lua_tolstring(lstate, -1, &len); @@ -2212,15 +2218,15 @@ char *nlua_read_secure(const char *path) memcpy(buf, contents, len + 1); } - // Pop return value, "vim", and "secure" - lua_pop(lstate, 3); - + lua_settop(lstate, top); return buf; } bool nlua_trust(const char *action, const char *path) { lua_State *const lstate = global_lstate; + const int top = lua_gettop(lstate); + lua_getglobal(lstate, "vim"); lua_getfield(lstate, -1, "secure"); lua_getfield(lstate, -1, "trust"); @@ -2241,6 +2247,7 @@ bool nlua_trust(const char *action, const char *path) if (nlua_pcall(lstate, 1, 2)) { nlua_error(lstate, _("Error executing vim.secure.trust: %.*s")); + lua_settop(lstate, top); return false; } @@ -2260,8 +2267,6 @@ bool nlua_trust(const char *action, const char *path) } } - // Pop return values, "vim" and "secure" - lua_pop(lstate, 4); - + lua_settop(lstate, top); return success; } diff --git a/test/functional/lua/secure_spec.lua b/test/functional/lua/secure_spec.lua index 6885253998..2647b2be46 100644 --- a/test/functional/lua/secure_spec.lua +++ b/test/functional/lua/secure_spec.lua @@ -150,10 +150,10 @@ describe('vim.secure', function() ]]} feed('v') screen:expect{grid=[[ - ^ let g:foobar = 42 | + ^let g:foobar = 42 | {1:~ }| {1:~ }| - {2:]] .. cwd .. pathsep .. [[Xfile [RO]{MATCH:%s+}| + {2:]] .. funcs.fnamemodify(cwd, ':~') .. pathsep .. [[Xfile [RO]{MATCH:%s+}| | {1:~ }| {4:[No Name] }| @@ -166,7 +166,7 @@ describe('vim.secure', function() -- Cannot write file pcall_err(command, 'write') - eq(false, curbufmeths.get_option('modifiable')) + eq(true, curbufmeths.get_option('readonly')) end) end) |