aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorii14 <59243201+ii14@users.noreply.github.com>2022-12-05 19:59:04 +0100
committerGitHub <noreply@github.com>2022-12-05 11:59:04 -0700
commitf3bf1fbf600050fde155e6a1a766b6f848012208 (patch)
tree4de99c04bf7d666ac15707e418468640c0946b1a
parent707df880545703bc6f4db1af6e46820becbcd911 (diff)
downloadrneovim-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.lua25
-rw-r--r--src/nvim/lua/executor.c19
-rw-r--r--test/functional/lua/secure_spec.lua6
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)