0
0
mirror of https://github.com/vim/vim.git synced 2025-09-23 03:43:49 -04:00

patch 8.2.1469: Vim9: cannot assign string to string option

Problem:    Vim9: cannot assign string to string option.
Solution:   Change checks for option value. (closes #6720)
This commit is contained in:
Bram Moolenaar
2020-08-16 21:29:05 +02:00
parent f923571ec1
commit 0aae4809fd
3 changed files with 56 additions and 26 deletions

View File

@@ -1294,28 +1294,36 @@ ex_let_one(
emsg(_(e_letunexp));
else
{
long n;
long n = 0;
int opt_type;
long numval;
char_u *stringval = NULL;
char_u *s = NULL;
int failed = FALSE;
c1 = *p;
*p = NUL;
opt_type = get_option_value(arg, &numval, &stringval, opt_flags);
if ((opt_type == 1 || opt_type == -1)
&& (tv->v_type != VAR_STRING || !in_vim9script()))
// number, possibly hidden
n = (long)tv_get_number(tv);
// avoid setting a string option to the text "v:false" or similar.
if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL)
s = tv_get_string_chk(tv); // != NULL if number or string
if (s != NULL && op != NULL && *op != '=')
// Avoid setting a string option to the text "v:false" or similar.
// In Vim9 script also don't convert a number to string.
if (tv->v_type != VAR_BOOL && tv->v_type != VAR_SPECIAL
&& (!in_vim9script() || tv->v_type != VAR_NUMBER))
s = tv_get_string_chk(tv);
if (op != NULL && *op != '=')
{
opt_type = get_option_value(arg, &numval,
&stringval, opt_flags);
if ((opt_type == 1 && *op == '.')
|| (opt_type == 0 && *op != '.'))
{
semsg(_(e_letwrong), op);
s = NULL; // don't set the value
failed = TRUE; // don't set the value
}
else
{
@@ -1330,20 +1338,26 @@ ex_let_one(
case '%': n = (long)num_modulus(numval, n); break;
}
}
else if (opt_type == 0 && stringval != NULL) // string
else if (opt_type == 0 && stringval != NULL && s != NULL)
{
// string
s = concat_str(stringval, s);
vim_free(stringval);
stringval = s;
}
}
}
if (s != NULL || tv->v_type == VAR_BOOL
|| tv->v_type == VAR_SPECIAL)
if (!failed)
{
if (opt_type != 0 || s != NULL)
{
set_option_value(arg, n, s, opt_flags);
arg_end = p;
}
else
emsg(_(e_stringreq));
}
*p = c1;
vim_free(stringval);
}

View File

@@ -96,22 +96,36 @@ def Test_assignment()
&ts += 3
assert_equal(9, &ts)
END
call CheckScriptSuccess(lines)
CheckScriptSuccess(lines)
call CheckDefFailure(['&notex += 3'], 'E113:')
call CheckDefFailure(['&ts ..= "xxx"'], 'E1019:')
call CheckDefFailure(['&ts = [7]'], 'E1012:')
call CheckDefExecFailure(['&ts = g:alist'], 'E1029: Expected number but got list')
call CheckDefFailure(['&ts = "xx"'], 'E1012:')
call CheckDefExecFailure(['&ts = g:astring'], 'E1029: Expected number but got string')
call CheckDefFailure(['&path += 3'], 'E1012:')
call CheckDefExecFailure(['&bs = "asdf"'], 'E474:')
CheckDefFailure(['&notex += 3'], 'E113:')
CheckDefFailure(['&ts ..= "xxx"'], 'E1019:')
CheckDefFailure(['&ts = [7]'], 'E1012:')
CheckDefExecFailure(['&ts = g:alist'], 'E1029: Expected number but got list')
CheckDefFailure(['&ts = "xx"'], 'E1012:')
CheckDefExecFailure(['&ts = g:astring'], 'E1029: Expected number but got string')
CheckDefFailure(['&path += 3'], 'E1012:')
CheckDefExecFailure(['&bs = "asdf"'], 'E474:')
# test freeing ISN_STOREOPT
call CheckDefFailure(['&ts = 3', 'let asdf'], 'E1022:')
CheckDefFailure(['&ts = 3', 'let asdf'], 'E1022:')
&ts = 8
call CheckDefFailure(['let s:var = 123'], 'E1101:')
call CheckDefFailure(['let s:var: number'], 'E1101:')
lines =<< trim END
let save_TI = &t_TI
&t_TI = ''
assert_equal('', &t_TI)
&t_TI = 'xxx'
assert_equal('xxx', &t_TI)
&t_TI = save_TI
END
CheckDefSuccess(lines)
CheckScriptSuccess(['vim9script'] + lines)
CheckDefFailure(['&t_TI = 123'], 'E1012:')
CheckScriptFailure(['vim9script', '&t_TI = 123'], 'E928:')
CheckDefFailure(['let s:var = 123'], 'E1101:')
CheckDefFailure(['let s:var: number'], 'E1101:')
lines =<< trim END
vim9script

View File

@@ -754,6 +754,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1469,
/**/
1468,
/**/