aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJames McCoy <jamessan@jamessan.com>2020-09-28 23:05:48 -0400
committerJames McCoy <jamessan@jamessan.com>2021-01-31 07:54:21 -0500
commita54ac073fb0a636717cdd8791e043d301a642726 (patch)
tree6ea98107a2c5f8bedcbad11a0b400c7732fee475 /src
parent8eec9c7d5b398918609d8edfed3928e873fa646f (diff)
downloadrneovim-a54ac073fb0a636717cdd8791e043d301a642726.tar.gz
rneovim-a54ac073fb0a636717cdd8791e043d301a642726.tar.bz2
rneovim-a54ac073fb0a636717cdd8791e043d301a642726.zip
eval/environ: Prefer the last definition of an env var
It's possible for the environment variable block given to nvim to contain multiple definitions for the same env var. In this case, nvim should preserve the last one defined.
Diffstat (limited to 'src')
-rw-r--r--src/nvim/eval/funcs.c8
1 files changed, 7 insertions, 1 deletions
diff --git a/src/nvim/eval/funcs.c b/src/nvim/eval/funcs.c
index 4486cd8f0d..7121d413ea 100644
--- a/src/nvim/eval/funcs.c
+++ b/src/nvim/eval/funcs.c
@@ -1798,7 +1798,7 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr)
os_copy_fullenv(env, env_size);
- for (size_t i = 0; i < env_size; i++) {
+ for (ssize_t i = env_size - 1; i >= 0; i--) {
const char * str = env[i];
const char * const end = strchr(str + (str[0] == '=' ? 1 : 0),
'=');
@@ -1806,6 +1806,12 @@ static void f_environ(typval_T *argvars, typval_T *rettv, FunPtr fptr)
ptrdiff_t len = end - str;
assert(len > 0);
const char * value = str + len + 1;
+ if (tv_dict_find(rettv->vval.v_dict, str, len) != NULL) {
+ // Since we're traversing from the end of the env block to the front, any
+ // duplicate names encountered should be ignored. This preserves the
+ // semantics of env vars defined later in the env block taking precedence.
+ continue;
+ }
tv_dict_add_str(rettv->vval.v_dict,
str, len,
value);