summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYegappan Lakshmanan <yegappan@yahoo.com>2024-05-08 20:24:33 +0200
committerChristian Brabandt <cb@256bit.org>2024-05-08 20:24:33 +0200
commit9937d8b61922a02311509fb3352583d9e8c54885 (patch)
treebbd19a2854e11b36e3ed535872e82fbe4d24352b
parentc7a8eb5ff2ddd919e6f39faec93d81c52874695a (diff)
patch 9.1.0398: Vim9: imported vars are not properly type checkedv9.1.0398
Problem: Vim9: imported vars are not properly type checked Solution: Check the imported variable type properly (Yegappan Lakshmanan) closes: #14729 Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com> Signed-off-by: Christian Brabandt <cb@256bit.org>
-rw-r--r--src/eval.c37
-rw-r--r--src/testdir/test_blob.vim12
-rw-r--r--src/testdir/test_vim9_assign.vim2
-rw-r--r--src/testdir/test_vim9_import.vim61
-rw-r--r--src/version.c2
5 files changed, 97 insertions, 17 deletions
diff --git a/src/eval.c b/src/eval.c
index a91ca2d3e5..b547143fe3 100644
--- a/src/eval.c
+++ b/src/eval.c
@@ -1170,12 +1170,10 @@ get_lval_check_access(
static char_u *
get_lval_imported(
lval_T *lp,
- typval_T *rettv,
scid_T imp_sid,
char_u *p,
dictitem_T **dip,
- int fne_flags,
- int vim9script)
+ int fne_flags)
{
ufunc_T *ufunc;
type_T *type = NULL;
@@ -1197,16 +1195,6 @@ get_lval_imported(
TRUE) == -1)
goto failed;
- if (vim9script && type != NULL)
- {
- where_T where = WHERE_INIT;
-
- // In a vim9 script, do type check and make sure the variable is
- // writable.
- if (check_typval_type(type, rettv, where) == FAIL)
- goto failed;
- }
-
// Get the typval for the exported item
hashtab_T *ht = &SCRIPT_VARS(imp_sid);
if (ht == NULL)
@@ -1232,6 +1220,7 @@ get_lval_imported(
goto failed;
lp->ll_tv = &di->di_tv;
+ lp->ll_valtype = type;
success:
rc = OK;
@@ -1410,8 +1399,7 @@ get_lval(
if (import != NULL)
{
p++; // skip '.'
- p = get_lval_imported(lp, rettv, import->imp_sid, p, &v,
- fne_flags, vim9script);
+ p = get_lval_imported(lp, import->imp_sid, p, &v, fne_flags);
if (p == NULL)
return NULL;
}
@@ -1754,6 +1742,12 @@ get_lval(
== FAIL)
return NULL;
}
+
+ if (!lp->ll_range)
+ // Indexing a single byte in a blob. So the rhs type is a
+ // number.
+ lp->ll_valtype = &t_number;
+
lp->ll_blob = lp->ll_tv->vval.v_blob;
lp->ll_tv = NULL;
break;
@@ -1782,7 +1776,7 @@ get_lval(
return NULL;
}
- if (lp->ll_valtype != NULL)
+ if (lp->ll_valtype != NULL && !lp->ll_range)
// use the type of the member
lp->ll_valtype = lp->ll_valtype->tt_member;
@@ -1896,6 +1890,17 @@ get_lval(
}
}
+ if (vim9script && lp->ll_valtype != NULL && rettv != NULL)
+ {
+ where_T where = WHERE_INIT;
+
+ // In a vim9 script, do type check and make sure the variable is
+ // writable.
+ if (check_typval_type(lp->ll_valtype, rettv, where) == FAIL)
+ return NULL;
+ }
+
+
clear_tv(&var1);
lp->ll_name_end = p;
return p;
diff --git a/src/testdir/test_blob.vim b/src/testdir/test_blob.vim
index cccecb7611..79487efa54 100644
--- a/src/testdir/test_blob.vim
+++ b/src/testdir/test_blob.vim
@@ -97,6 +97,18 @@ func Test_blob_assign()
let lines =<< trim END
VAR b = 0zDEADBEEF
+ LET b[0 : 1] = 0x1122
+ END
+ call v9.CheckLegacyAndVim9Failure(lines, ['E709:', 'E1012:', 'E709:'])
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
+ LET b[0] = 0z11
+ END
+ call v9.CheckLegacyAndVim9Failure(lines, ['E974:', 'E974:', 'E1012:'])
+
+ let lines =<< trim END
+ VAR b = 0zDEADBEEF
LET b ..= 0z33
END
call v9.CheckLegacyAndVim9Failure(lines, ['E734:', 'E1019:', 'E734:'])
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index 4296c37092..7a72edce00 100644
--- a/src/testdir/test_vim9_assign.vim
+++ b/src/testdir/test_vim9_assign.vim
@@ -650,7 +650,7 @@ def Test_assign_index()
var bl = 0z11
bl[1] = g:val
END
- v9.CheckDefExecAndScriptFailure(lines, 'E1030: Using a String as a Number: "22"')
+ v9.CheckDefExecAndScriptFailure(lines, ['E1030: Using a String as a Number: "22"', 'E1012: Type mismatch; expected number but got string'])
# should not read the next line when generating "a.b"
var a = {}
diff --git a/src/testdir/test_vim9_import.vim b/src/testdir/test_vim9_import.vim
index 581925d24c..94e0f34a33 100644
--- a/src/testdir/test_vim9_import.vim
+++ b/src/testdir/test_vim9_import.vim
@@ -3222,4 +3222,65 @@ def Test_autoload_import_dict_func()
&rtp = save_rtp
enddef
+" Test for changing the value of an imported Dict item
+def Test_set_imported_dict_item()
+ var lines =<< trim END
+ vim9script
+ export var dict1: dict<bool> = {bflag: false}
+ export var dict2: dict<dict<bool>> = {x: {bflag: false}}
+ END
+ writefile(lines, 'XimportedDict.vim', 'D')
+
+ lines =<< trim END
+ vim9script
+ import './XimportedDict.vim'
+ assert_equal(XimportedDict.dict1.bflag, false)
+ XimportedDict.dict1.bflag = true
+ assert_equal(XimportedDict.dict1.bflag, true)
+ XimportedDict.dict2.x.bflag = true
+ assert_equal(XimportedDict.dict2.x.bflag, true)
+ assert_equal('bool', typename(XimportedDict.dict1.bflag))
+ assert_equal('bool', typename(XimportedDict.dict2.x.bflag))
+ assert_equal('bool', typename(XimportedDict.dict2['x'].bflag))
+ assert_equal('bool', typename(XimportedDict.dict2.x['bflag']))
+
+ assert_equal(XimportedDict.dict1['bflag'], true)
+ XimportedDict.dict1['bflag'] = false
+ assert_equal(XimportedDict.dict1.bflag, false)
+ XimportedDict.dict2['x']['bflag'] = false
+ assert_equal(XimportedDict.dict2['x'].bflag, false)
+ END
+ v9.CheckScriptSuccess(lines)
+
+ lines =<< trim END
+ vim9script
+ import './XimportedDict.vim'
+ XimportedDict.dict2.x.bflag = []
+ END
+ v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected bool but got list<any>', 3)
+enddef
+
+" Test for changing the value of an imported class member
+def Test_set_imported_class_member()
+ var lines =<< trim END
+ vim9script
+ export class Config
+ public static var option = false
+ endclass
+ END
+ writefile(lines, 'XimportedClass.vim', 'D')
+
+ lines =<< trim END
+ vim9script
+ import './XimportedClass.vim' as foo
+ type FooConfig = foo.Config
+ assert_equal(false, FooConfig.option)
+ assert_equal(false, foo.Config.option)
+ foo.Config.option = true
+ assert_equal(true, foo.Config.option)
+ assert_equal(true, FooConfig.option)
+ END
+ v9.CheckScriptSuccess(lines)
+enddef
+
" vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
diff --git a/src/version.c b/src/version.c
index ab38373214..ba03c1a506 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 398,
+/**/
397,
/**/
396,