]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0861: Vim9: no runtime check for object member access of any var v9.1.0861
authorYegappan Lakshmanan <yegappan@yahoo.com>
Tue, 12 Nov 2024 20:03:00 +0000 (21:03 +0100)
committerChristian Brabandt <cb@256bit.org>
Tue, 12 Nov 2024 20:03:00 +0000 (21:03 +0100)
Problem:  Vim9: no runtime check for object member access of any var
          (after: 9.1.0850)
Solution: Add runtime type compatibility check for object member
          accessed using a any variable (Yegappan Lakshmanan).

closes: #16037

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/testdir/test_vim9_class.vim
src/version.c
src/vim9execute.c

index 4ce9fcdc49e04c0ca3ec7086cf82caeaafa23dff..d8a3fa383fbe1200c5ac89db09caadc3f2a07d66 100644 (file)
@@ -11546,6 +11546,54 @@ def Test_any_obj_var_type()
     Fn(null_object)
   END
   v9.CheckScriptFailure(lines, 'E1360: Using a null object', 1)
+
+  # Try to change a const object variable using a "any" variable
+  lines =<< trim END
+    vim9script
+    class A
+      public const v1: number = 123
+    endclass
+
+    def Fn(o: any)
+      o.v1 = 321
+    enddef
+
+    var a = A.new()
+    Fn(a)
+  END
+  v9.CheckScriptFailure(lines, 'E1409: Cannot change read-only variable "v1" in class "A"', 1)
+
+  # Try to change a final object variable using a "any" variable
+  lines =<< trim END
+    vim9script
+    class A
+      public final v1: number = 123
+    endclass
+
+    def Fn(o: any)
+      o.v1 = 321
+    enddef
+
+    var a = A.new()
+    Fn(a)
+  END
+  v9.CheckScriptFailure(lines, 'E1409: Cannot change read-only variable "v1" in class "A"', 1)
+
+  # Assign a different type of value to an "any" type object variable
+  lines =<< trim END
+    vim9script
+    class A
+      public var v1: list<any> = [1, 2]
+    endclass
+
+    def Fn(o: A)
+      o.v1 = 'abc'
+    enddef
+
+    var a = A.new()
+    Fn(a)
+  END
+  v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected list<any> but got string', 1)
 enddef
 
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index 798598568922c4017a54b40a4641c2b521287c81..f2e9473f7edecdb4fe70728d791b6c7b2c3c034f 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    861,
 /**/
     860,
 /**/
index da03d5e7d4535e58fad3bd99b1df7799a845d07c..7ab6813a6955e08b82acc66716ae2b969bdce3d9 100644 (file)
@@ -2271,6 +2271,7 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
                    // Get the current function
                    ufunc_T *ufunc = (((dfunc_T *)def_functions.ga_data)
                                        + ectx->ec_dfunc_idx)->df_ufunc;
+                   where_T where = WHERE_INIT;
 
                    // Check whether the member variable is writeable
                    if ((m->ocm_access != VIM_ACCESS_ALL) &&
@@ -2283,6 +2284,12 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
                        emsg_var_cl_define(msg, m->ocm_name, 0, cl);
                        status = FAIL;
                    }
+                   // Fail if the variable is a const or final or the type
+                   // is not compatible
+                   else if (oc_var_check_ro(cl, m) ||
+                            check_typval_type(m->ocm_type, tv, where)
+                                                               == FAIL)
+                       status = FAIL;
                    else
                        lidx = m_idx;
                }