feat(exrc): use vim.secure.read() for 'exrc' option

This commit is contained in:
Gregory Anders
2022-11-05 19:30:48 -06:00
parent f1922e78a1
commit 294910a1ff
7 changed files with 53 additions and 6 deletions

View File

@@ -128,10 +128,6 @@ NORMAL COMMANDS
OPTIONS OPTIONS
- *cpo-<* *:menu-<special>* *:menu-special* *:map-<special>* *:map-special* - *cpo-<* *:menu-<special>* *:menu-special* *:map-<special>* *:map-special*
`<>` notation is always enabled. `<>` notation is always enabled.
- *'exrc'* *'ex'* Security risk: downloaded files could include
a malicious .nvimrc or .exrc file. See 'secure'.
Recommended alternative: define an autocommand in your
|vimrc| to set options for a matching directory.
- 'gdefault' Enables the |:substitute| flag 'g' by default. - 'gdefault' Enables the |:substitute| flag 'g' by default.
- *'fe'* 'fenc'+'enc' before Vim 6.0; no longer used. - *'fe'* 'fenc'+'enc' before Vim 6.0; no longer used.
- *'highlight'* *'hl'* Names of builtin |highlight-groups| cannot be changed. - *'highlight'* *'hl'* Names of builtin |highlight-groups| cannot be changed.

View File

@@ -60,6 +60,8 @@ CHANGED FEATURES *news-changes*
The following changes to existing APIs or features add new behavior. The following changes to existing APIs or features add new behavior.
• 'exrc' is no longer marked deprecated.
============================================================================== ==============================================================================
REMOVED FEATURES *news-removed* REMOVED FEATURES *news-removed*

View File

@@ -2264,6 +2264,20 @@ A jump table for the options with a short description can be found at |Q_op|.
This option is reset when the 'paste' option is set and restored when This option is reset when the 'paste' option is set and restored when
the 'paste' option is reset. the 'paste' option is reset.
*'exrc'* *'ex'* *'noexrc'* *'noex'*
'exrc' 'ex' boolean (default off)
global
Enables the reading of .nvimrc and .exrc files in the current
directory.
The file is only sourced if the user indicates the file is trusted. If
it is, the SHA256 hash of the file contents and the full path of the
file are persisted to a trust database. The user is only prompted
again if the file contents change. See |vim.secure.read()|.
This option cannot be set from a |modeline| or in the |sandbox|, for
security reasons.
*'fileencoding'* *'fenc'* *E213* *'fileencoding'* *'fenc'* *E213*
'fileencoding' 'fenc' string (default: "") 'fileencoding' 'fenc' string (default: "")
local to buffer local to buffer

View File

@@ -417,6 +417,8 @@ Options:
'jumpoptions' "view" tries to restore the |mark-view| when moving through 'jumpoptions' "view" tries to restore the |mark-view| when moving through
the |jumplist|, |changelist|, |alternate-file| or using |mark-motions|. the |jumplist|, |changelist|, |alternate-file| or using |mark-motions|.
'shortmess' the "F" flag does not affect output from autocommands 'shortmess' the "F" flag does not affect output from autocommands
'exrc' searches for ".nvimrc" or ".exrc" files. The user is prompted whether
to trust the file.
Shell: Shell:
Shell output (|:!|, |:make|, …) is always routed through the UI, so it Shell output (|:!|, |:make|, …) is always routed through the UI, so it

View File

@@ -2193,3 +2193,27 @@ plain:
kv_printf(str, "<Lua %d>", ref); kv_printf(str, "<Lua %d>", ref);
return str.items; return str.items;
} }
char *nlua_read_secure(const char *path)
{
lua_State *const lstate = global_lstate;
lua_getglobal(lstate, "vim");
lua_getfield(lstate, -1, "secure");
lua_getfield(lstate, -1, "read");
lua_pushstring(lstate, path);
lua_call(lstate, 1, 1);
size_t len = 0;
const char *contents = lua_tolstring(lstate, -1, &len);
char *buf = NULL;
if (contents != NULL) {
// Add one to include trailing null byte
buf = xcalloc(len + 1, sizeof(char));
memcpy(buf, contents, len + 1);
}
// Pop return value, "vim", and "secure"
lua_pop(lstate, 3);
return buf;
}

View File

@@ -2002,7 +2002,11 @@ static void source_startup_scripts(const mparm_T *const parmp)
#endif #endif
secure = p_secure; secure = p_secure;
if (do_source(VIMRC_FILE, true, DOSO_VIMRC) == FAIL) { char *str = nlua_read_secure(VIMRC_FILE);
if (str != NULL) {
do_source_str(str, VIMRC_FILE);
xfree(str);
} else {
#if defined(UNIX) #if defined(UNIX)
// if ".exrc" is not owned by user set 'secure' mode // if ".exrc" is not owned by user set 'secure' mode
if (!os_file_owned(EXRC_FILE)) { if (!os_file_owned(EXRC_FILE)) {
@@ -2011,7 +2015,11 @@ static void source_startup_scripts(const mparm_T *const parmp)
secure = 0; secure = 0;
} }
#endif #endif
(void)do_source(EXRC_FILE, false, DOSO_NONE); str = nlua_read_secure(EXRC_FILE);
if (str != NULL) {
do_source_str(str, EXRC_FILE);
xfree(str);
}
} }
} }
if (secure == 2) { if (secure == 2) {

View File

@@ -1024,6 +1024,7 @@ endfunc
" Test for using the 'exrc' option " Test for using the 'exrc' option
func Test_exrc() func Test_exrc()
throw 'Skipped: Nvim requires user input for the exrc option'
let after =<< trim [CODE] let after =<< trim [CODE]
call assert_equal(1, &exrc) call assert_equal(1, &exrc)
call assert_equal(1, &secure) call assert_equal(1, &secure)