From: Yegappan Lakshmanan Date: Sun, 21 Dec 2025 19:03:31 +0000 (+0000) Subject: patch 9.1.2002: Vim9: heap-use-after-free when when accessing protect class member X-Git-Tag: v9.1.2002^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c1d77520b8baad9f3d53e9f57b416aee3b25a069;p=thirdparty%2Fvim.git patch 9.1.2002: Vim9: heap-use-after-free when when accessing protect class member Problem: Vim9: heap-use-after-free when when accessing protect class member (Foxe Chen) Solution: Set cl->class_type_list and return directly, add tests for using protected class method and variable from another class (Yegappan Lakshmanan). closes: #18971 Signed-off-by: Yegappan Lakshmanan Signed-off-by: Christian Brabandt --- diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim index 6ec7ffa6e2..d0260c202c 100644 --- a/src/testdir/test_vim9_class.vim +++ b/src/testdir/test_vim9_class.vim @@ -5245,7 +5245,7 @@ def Test_lockvar_islocked_notfound() enddef " Test for a protected object method -def Test_private_object_method() +def Test_protected_object_method() # Try calling a protected method using an object (at the script level) var lines =<< trim END vim9script @@ -5482,10 +5482,27 @@ def Test_private_object_method() var a = _Foo() END v9.CheckSourceFailure(lines, 'E1267: Function name must start with a capital: _Foo(): number', 2) + + # Test for initializing a protected funcref instance variable to a protected + # class method from another class + lines =<< trim END + vim9script + + class A + static def _Internal(): string + enddef + endclass + + class B + var Fn: func = A._Internal + endclass + var b = B.new() + END + v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Internal', 1) enddef " Test for an protected class method -def Test_private_class_method() +def Test_protected_class_method() # Try calling a class protected method (at the script level) var lines =<< trim END vim9script @@ -5680,6 +5697,22 @@ def Test_private_class_method() assert_equal(1234, C._Foo()) END v9.CheckSourceFailure(lines, 'E1325: Method "_Foo" not found in class "C"', 16) + + # Test for initializing a protected funcref class variable to a protected + # class method from another class + lines =<< trim END + vim9script + + class A + static def _Internal(): string + enddef + endclass + + class B + static var Fn: func = A._Internal + endclass + END + v9.CheckSourceFailure(lines, 'E1366: Cannot access protected method: _Internal', 10) enddef " Test for using the return value of a class/object method as a function @@ -5938,15 +5971,12 @@ def Test_dup_member_variable() enddef " Test for accessing a protected member outside a class in a def function -def Test_private_member_access_outside_class() - # protected object member variable +def Test_protected_member_access_outside_class() + # try to modify a protected instance variable from a def function var lines =<< trim END vim9script class A var _val = 10 - def GetVal(): number - return this._val - enddef endclass def T() var a = A.new() @@ -5956,7 +5986,7 @@ def Test_private_member_access_outside_class() END v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 2) - # access a non-existing protected object member variable + # access a non-existing protected instance variable from a def function lines =<< trim END vim9script class A @@ -5970,7 +6000,7 @@ def Test_private_member_access_outside_class() END v9.CheckSourceFailure(lines, 'E1326: Variable "_a" not found in object "A"', 2) - # protected static member variable + # try to read a protected class variable from a def function using an instance lines =<< trim END vim9script class A @@ -5984,7 +6014,8 @@ def Test_private_member_access_outside_class() END v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2) - # protected static member variable + # try to modify a protected class variable from a def function using an + # instance lines =<< trim END vim9script class A @@ -5998,7 +6029,7 @@ def Test_private_member_access_outside_class() END v9.CheckSourceFailure(lines, 'E1375: Class variable "_val" accessible only using class "A"', 2) - # protected static class variable + # try to read a protected class variable from a def function using the class lines =<< trim END vim9script class A @@ -6011,7 +6042,7 @@ def Test_private_member_access_outside_class() END v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1) - # protected static class variable + # try to modify a protected class variable from a def function using the class lines =<< trim END vim9script class A @@ -6023,6 +6054,33 @@ def Test_private_member_access_outside_class() T() END v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_val" in class "A"', 1) + + # initialize a protected class variable using a protected class variable + # from another class + lines =<< trim END + vim9script + class A + static var _aval = 10 + endclass + class B + static var _bval = A._aval + endclass + END + v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_aval" in class "A"', 7) + + # initialize a protected instance variable using a protected class variable + # from another class + lines =<< trim END + vim9script + class A + static var _aval = 10 + endclass + class B + var _bval = A._aval + endclass + var b = B.new() + END + v9.CheckSourceFailure(lines, 'E1333: Cannot access protected variable "_aval" in class "A"', 1) enddef " Test for changing the member access of an interface in a implementation class @@ -7088,7 +7146,7 @@ def Test_extend_empty_class() v9.CheckSourceSuccess(lines) enddef -" A interface cannot have a static variable or a static method or a private +" A interface cannot have a static variable or a static method or a protected " variable or a protected method or a public variable def Test_interface_with_unsupported_members() var lines =<< trim END @@ -11686,7 +11744,7 @@ def Test_any_obj_var_type() END v9.CheckScriptSuccess(lines) - # Modifying an object private variable from a method in another class using + # Modifying an object protected variable from a method in another class using # any type lines =<< trim END vim9script @@ -11756,7 +11814,7 @@ def Test_any_obj_var_type() END v9.CheckScriptSuccess(lines) - # Try to modify a private object variable using a variable of type "any" + # Try to modify a protected object variable using a variable of type "any" lines =<< trim END vim9script diff --git a/src/version.c b/src/version.c index a8602f71b2..534d365e58 100644 --- a/src/version.c +++ b/src/version.c @@ -734,6 +734,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ +/**/ + 2002, /**/ 2001, /**/ diff --git a/src/vim9class.c b/src/vim9class.c index ea91706f06..e5b811b915 100644 --- a/src/vim9class.c +++ b/src/vim9class.c @@ -2700,7 +2700,10 @@ early_ret: // Allocate a typval for each class member and initialize it. if ((is_class || is_enum) && cl->class_class_member_count > 0) if (add_class_members(cl, eap, &type_list) == FAIL) - goto cleanup; + { + cl->class_type_list = type_list; + return; + } cl->class_type_list = type_list;