aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-09-22 21:34:46 +0800
committerGitHub <noreply@github.com>2022-09-22 21:34:46 +0800
commit11f91ac304e7f4d96b8c5f7e056bf941da32466b (patch)
treedd5d91e1be996fe4504938a4dd984f8b63953a56
parent5c1b8d7bf80d03c70a5972432ac11e60e903d232 (diff)
parent4371886293b4956530f8bec49b01c0ee02771434 (diff)
downloadrneovim-11f91ac304e7f4d96b8c5f7e056bf941da32466b.tar.gz
rneovim-11f91ac304e7f4d96b8c5f7e056bf941da32466b.tar.bz2
rneovim-11f91ac304e7f4d96b8c5f7e056bf941da32466b.zip
Merge pull request #20287 from zeertzjq/vim-9.0.0540
vim-patch:9.0.{0540,0544}: assigning stack variable to argument confuses Coverity
-rw-r--r--src/nvim/option.c54
-rw-r--r--src/nvim/testdir/test_options.vim14
2 files changed, 41 insertions, 27 deletions
diff --git a/src/nvim/option.c b/src/nvim/option.c
index 2a45f3b38b..5b67f0e471 100644
--- a/src/nvim/option.c
+++ b/src/nvim/option.c
@@ -779,10 +779,11 @@ void ex_set(exarg_T *eap)
/// Part of do_set() for string options.
/// @return FAIL on failure, do not process further options.
-static int do_set_string(int opt_idx, int opt_flags, char **arg, int nextchar, set_op_T op_arg,
+static int do_set_string(int opt_idx, int opt_flags, char **argp, int nextchar, set_op_T op_arg,
uint32_t flags, char *varp_arg, char *errbuf, size_t errbuflen,
int *value_checked, char **errmsg)
{
+ char *arg = *argp;
set_op_T op = op_arg;
char *varp = varp_arg;
char *save_arg = NULL;
@@ -849,15 +850,13 @@ static int do_set_string(int opt_idx, int opt_flags, char **arg, int nextchar, s
} else if (nextchar == '<') { // set to global val
newval = xstrdup(*(char **)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL));
} else {
- (*arg)++; // jump to after the '=' or ':'
+ arg++; // jump to after the '=' or ':'
// Set 'keywordprg' to ":help" if an empty
// value was passed to :set by the user.
- // Misuse errbuf[] for the resulting string.
- if (varp == (char *)&p_kp && (**arg == NUL || **arg == ' ')) {
- STRCPY(errbuf, ":help");
- save_arg = *arg;
- *arg = errbuf;
+ if (varp == (char *)&p_kp && (*arg == NUL || *arg == ' ')) {
+ save_arg = arg;
+ arg = ":help";
} else if (varp == (char *)&p_bs && ascii_isdigit(**(char_u **)varp)) {
// Convert 'backspace' number to string, for
// adding, prepending and removing string.
@@ -887,11 +886,11 @@ static int do_set_string(int opt_idx, int opt_flags, char **arg, int nextchar, s
origval_g = *(char_u **)varp;
}
oldval = *(char_u **)varp;
- } else if (varp == (char *)&p_ww && ascii_isdigit(**arg)) {
+ } else if (varp == (char *)&p_ww && ascii_isdigit(*arg)) {
// Convert 'whichwrap' number to string, for backwards compatibility
// with Vim 3.0.
*whichwrap = NUL;
- int i = getdigits_int(arg, true, 0);
+ int i = getdigits_int(&arg, true, 0);
if (i & 1) {
xstrlcat(whichwrap, "b,", sizeof(whichwrap));
}
@@ -910,12 +909,12 @@ static int do_set_string(int opt_idx, int opt_flags, char **arg, int nextchar, s
if (*whichwrap != NUL) { // remove trailing ,
whichwrap[strlen(whichwrap) - 1] = NUL;
}
- save_arg = *arg;
- *arg = whichwrap;
- } else if (**arg == '>' && (varp == (char *)&p_dir || varp == (char *)&p_bdir)) {
+ save_arg = arg;
+ arg = whichwrap;
+ } else if (*arg == '>' && (varp == (char *)&p_dir || varp == (char *)&p_bdir)) {
// Remove '>' before 'dir' and 'bdir', for backwards compatibility with
// version 3.0
- (*arg)++;
+ arg++;
}
// Copy the new string into allocated memory.
@@ -923,7 +922,7 @@ static int do_set_string(int opt_idx, int opt_flags, char **arg, int nextchar, s
// backslashes.
// get a bit too much
- newlen = (unsigned)strlen(*arg) + 1;
+ newlen = (unsigned)strlen(arg) + 1;
if (op != OP_NONE) {
newlen += (unsigned)STRLEN(origval) + 1;
}
@@ -935,26 +934,26 @@ static int do_set_string(int opt_idx, int opt_flags, char **arg, int nextchar, s
// are not removed, and keep backslash at start, for "\\machine\path",
// but do remove it for "\\\\machine\\path".
// The reverse is found in ExpandOldSetting().
- while (**arg && !ascii_iswhite(**arg)) {
- if (**arg == '\\' && (*arg)[1] != NUL
+ while (*arg != NUL && !ascii_iswhite(*arg)) {
+ if (*arg == '\\' && arg[1] != NUL
#ifdef BACKSLASH_IN_FILENAME
&& !((flags & P_EXPAND)
- && vim_isfilec((*arg)[1])
- && !ascii_iswhite((*arg)[1])
- && ((*arg)[1] != '\\'
- || (s == newval && (*arg)[2] != '\\')))
+ && vim_isfilec(arg[1])
+ && !ascii_iswhite(arg[1])
+ && (arg[1] != '\\'
+ || (s == newval && arg[2] != '\\')))
#endif
) {
- (*arg)++; // remove backslash
+ arg++; // remove backslash
}
- int i = utfc_ptr2len(*arg);
+ int i = utfc_ptr2len(arg);
if (i > 1) {
// copy multibyte char
- memmove(s, *arg, (size_t)i);
- *arg += i;
+ memmove(s, arg, (size_t)i);
+ arg += i;
s += i;
} else {
- *s++ = *(*arg)++;
+ *s++ = *arg++;
}
}
*s = NUL;
@@ -1061,8 +1060,8 @@ static int do_set_string(int opt_idx, int opt_flags, char **arg, int nextchar, s
}
}
- if (save_arg != NULL) { // number for 'whichwrap'
- *arg = save_arg;
+ if (save_arg != NULL) {
+ arg = save_arg; // arg was temporarily changed, restore it
}
}
@@ -1117,6 +1116,7 @@ static int do_set_string(int opt_idx, int opt_flags, char **arg, int nextchar, s
xfree(saved_origval_g);
xfree(saved_newval);
+ *argp = arg;
return *errmsg == NULL ? OK : FAIL;
}
diff --git a/src/nvim/testdir/test_options.vim b/src/nvim/testdir/test_options.vim
index 952975df32..ada6d2406b 100644
--- a/src/nvim/testdir/test_options.vim
+++ b/src/nvim/testdir/test_options.vim
@@ -1209,4 +1209,18 @@ func Test_switchbuf_reset()
only!
endfunc
+" :set empty string for global 'keywordprg' falls back to ":help"
+func Test_keywordprg_empty()
+ let k = &keywordprg
+ set keywordprg=man
+ call assert_equal('man', &keywordprg)
+ set keywordprg=
+ call assert_equal(':help', &keywordprg)
+ set keywordprg=man
+ call assert_equal('man', &keywordprg)
+ call assert_equal("\n keywordprg=:help", execute('set kp= kp?'))
+ let &keywordprg = k
+endfunc
+
+
" vim: shiftwidth=2 sts=2 expandtab