patch 9.1.0398: Vim9: imported vars are not properly type checked

Commit: 
https://github.com/vim/vim/commit/9937d8b61922a02311509fb3352583d9e8c54885
Author: Yegappan Lakshmanan <yegap...@yahoo.com>
Date:   Wed May 8 20:24:33 2024 +0200

    patch 9.1.0398: Vim9: imported vars are not properly type checked
    
    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 <yegap...@yahoo.com>
    Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/src/eval.c b/src/eval.c
index a91ca2d3e..b547143fe 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 cccecb761..79487efa5 100644
--- a/src/testdir/test_blob.vim
+++ b/src/testdir/test_blob.vim
@@ -95,6 +95,18 @@ func Test_blob_assign()
   END
   call v9.CheckLegacyAndVim9Failure(lines, 'E979:')
 
+  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
diff --git a/src/testdir/test_vim9_assign.vim b/src/testdir/test_vim9_assign.vim
index 4296c3709..7a72edce0 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 581925d24..94e0f34a3 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 ab3837321..ba03c1a50 100644
--- a/src/version.c
+++ b/src/version.c
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    398,
 /**/
     397,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to vim_dev+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/vim_dev/E1s4m3L-006Xm0-6O%40256bit.org.

Raspunde prin e-mail lui