]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.0.1824: Vim9: private members may be modifiable v9.0.1824
authorYegappan Lakshmanan <yegappan@yahoo.com>
Wed, 30 Aug 2023 14:38:26 +0000 (16:38 +0200)
committerChristian Brabandt <cb@256bit.org>
Wed, 30 Aug 2023 14:40:33 +0000 (16:40 +0200)
Problem:  Vim9: private members may be modifiable
Solution: prevent modification for def function

closes: #12963

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

index 97be92d1a23e7de774b09dbcf468a842429bca7f..ad0be5b5114490ad578ff5f19c4dcf72253c5fbd 100644 (file)
@@ -3653,4 +3653,37 @@ def Test_dup_member_variable()
   v9.CheckScriptFailure(lines, 'E1369: Duplicate member: val')
 enddef
 
+" Test for accessing a private member outside a class in a def function
+def Test_private_member_access_outside_class()
+  # private object member variable
+  var lines =<< trim END
+    vim9script
+    class A
+      this._val = 10
+      def GetVal(): number
+        return this._val
+      enddef
+    endclass
+    def T()
+      var a = A.new()
+      a._val = 20
+    enddef
+    T()
+  END
+  v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val')
+
+  # private class member variable
+  lines =<< trim END
+    vim9script
+    class A
+      static _val: number = 10
+    endclass
+    def T()
+      A._val = 20
+    enddef
+    T()
+  END
+  v9.CheckScriptFailure(lines, 'E1333: Cannot access private member: _val')
+enddef
+
 " vim: ts=8 sw=2 sts=2 expandtab tw=80 fdm=marker
index bb6f52a7f7ce7756255aa58582d6d775081c348f..843db4c5bb0e827c3b071e01c0a02f7e215a92ac 100644 (file)
@@ -699,6 +699,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1824,
 /**/
     1823,
 /**/
index add9eda60b5ad725617452c6e0c04a1240898304..5c173c190dcf5ed5e205a4c8d0044cd5ef6c9292 100644 (file)
@@ -1866,6 +1866,15 @@ compile_lhs(
        {
            // for an object or class member get the type of the member
            class_T *cl = lhs->lhs_type->tt_class;
+           // If it is private member variable, then accessing it outside the
+           // class is not allowed.
+           if (*(after + 1) == '_' && !inside_class(cctx, cl))
+           {
+               char_u *m_name = vim_strnsave(after + 1, lhs->lhs_end - after);
+               semsg(_(e_cannot_access_private_member_str), m_name);
+               vim_free(m_name);
+               return FAIL;
+           }
            lhs->lhs_member_type = class_member_type(cl, after + 1,
                                           lhs->lhs_end, &lhs->lhs_member_idx);
            if (lhs->lhs_member_idx < 0)