Skip to content

Commit d2f4800

Browse files
yegappanchrisbra
authored andcommitted
patch 9.0.1988: Vim9: potential use-after-free for class members
Problem: Vim9: potential use-after-free for class members Solution: Use the class-related grow array for storing the member type instead of using a temporary type list grow array Use the type list grow array associated with the class than using a temporary type list grow array to allocate the class member type. For simple types, a predefined type is used. For complex types, the type is dynamically allocated from a grow array. For class variables, the type grow array in the class should be used. So that the lifetime of the type is same as the lifetime of the class. closes: #13279 Signed-off-by: Christian Brabandt <[email protected]> Co-authored-by: Yegappan Lakshmanan <[email protected]>
1 parent da5da65 commit d2f4800

3 files changed

Lines changed: 68 additions & 58 deletions

File tree

src/testdir/test_vim9_class.vim

Lines changed: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -6483,26 +6483,26 @@ func Test_class_variable_complex_type_check()
64836483
" script level.
64846484
let lines =<< trim END
64856485
vim9script
6486-
def Foo(l: list<dict<number>>): dict<list<number>>
6486+
def Foo(l: list<dict<blob>>): dict<list<blob>>
64876487
return {}
64886488
enddef
64896489
class A
6490-
public static Fn: func(list<dict<number>>): dict<list<number>> = Foo
6490+
public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
64916491
endclass
64926492
test_garbagecollect_now()
64936493
A.Fn = "abc"
64946494
END
6495-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 9)
6495+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 9)
64966496

64976497
" class variable with a specific type. Try assigning a different type at
64986498
" class def method level.
64996499
let lines =<< trim END
65006500
vim9script
6501-
def Foo(l: list<dict<number>>): dict<list<number>>
6501+
def Foo(l: list<dict<blob>>): dict<list<blob>>
65026502
return {}
65036503
enddef
65046504
class A
6505-
public static Fn: func(list<dict<number>>): dict<list<number>> = Foo
6505+
public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
65066506
def Bar()
65076507
Fn = "abc"
65086508
enddef
@@ -6511,31 +6511,31 @@ func Test_class_variable_complex_type_check()
65116511
test_garbagecollect_now()
65126512
a.Bar()
65136513
END
6514-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1)
6514+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
65156515

65166516
" class variable with a specific type. Try assigning a different type at
65176517
" script def method level.
65186518
let lines =<< trim END
65196519
vim9script
6520-
def Foo(l: list<dict<number>>): dict<list<number>>
6520+
def Foo(l: list<dict<blob>>): dict<list<blob>>
65216521
return {}
65226522
enddef
65236523
class A
6524-
public static Fn: func(list<dict<number>>): dict<list<number>> = Foo
6524+
public static Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
65256525
endclass
65266526
def Bar()
65276527
A.Fn = "abc"
65286528
enddef
65296529
test_garbagecollect_now()
65306530
Bar()
65316531
END
6532-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1)
6532+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
65336533

65346534
" class variable without any type. Should be set to the initialization
65356535
" expression type. Try assigning a different type from script level.
65366536
let lines =<< trim END
65376537
vim9script
6538-
def Foo(l: list<dict<number>>): dict<list<number>>
6538+
def Foo(l: list<dict<blob>>): dict<list<blob>>
65396539
return {}
65406540
enddef
65416541
class A
@@ -6544,13 +6544,13 @@ func Test_class_variable_complex_type_check()
65446544
test_garbagecollect_now()
65456545
A.Fn = "abc"
65466546
END
6547-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 9)
6547+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 9)
65486548

65496549
" class variable without any type. Should be set to the initialization
65506550
" expression type. Try assigning a different type at class def level.
65516551
let lines =<< trim END
65526552
vim9script
6553-
def Foo(l: list<dict<number>>): dict<list<number>>
6553+
def Foo(l: list<dict<blob>>): dict<list<blob>>
65546554
return {}
65556555
enddef
65566556
class A
@@ -6563,13 +6563,13 @@ func Test_class_variable_complex_type_check()
65636563
test_garbagecollect_now()
65646564
a.Bar()
65656565
END
6566-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1)
6566+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
65676567

65686568
" class variable without any type. Should be set to the initialization
65696569
" expression type. Try assigning a different type at script def level.
65706570
let lines =<< trim END
65716571
vim9script
6572-
def Foo(l: list<dict<number>>): dict<list<number>>
6572+
def Foo(l: list<dict<blob>>): dict<list<blob>>
65736573
return {}
65746574
enddef
65756575
class A
@@ -6581,26 +6581,26 @@ func Test_class_variable_complex_type_check()
65816581
test_garbagecollect_now()
65826582
Bar()
65836583
END
6584-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1)
6584+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
65856585

65866586
" class variable with 'any" type. Can be assigned different types.
65876587
let lines =<< trim END
65886588
vim9script
6589-
def Foo(l: list<dict<number>>): dict<list<number>>
6589+
def Foo(l: list<dict<blob>>): dict<list<blob>>
65906590
return {}
65916591
enddef
65926592
class A
65936593
public static Fn: any = Foo
65946594
public static Fn2: any
65956595
endclass
65966596
test_garbagecollect_now()
6597-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(A.Fn))
6597+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
65986598
A.Fn = "abc"
65996599
test_garbagecollect_now()
66006600
assert_equal('string', typename(A.Fn))
66016601
A.Fn2 = Foo
66026602
test_garbagecollect_now()
6603-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(A.Fn2))
6603+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
66046604
A.Fn2 = "xyz"
66056605
test_garbagecollect_now()
66066606
assert_equal('string', typename(A.Fn2))
@@ -6610,19 +6610,19 @@ func Test_class_variable_complex_type_check()
66106610
" class variable with 'any" type. Can be assigned different types.
66116611
let lines =<< trim END
66126612
vim9script
6613-
def Foo(l: list<dict<number>>): dict<list<number>>
6613+
def Foo(l: list<dict<blob>>): dict<list<blob>>
66146614
return {}
66156615
enddef
66166616
class A
66176617
public static Fn: any = Foo
66186618
public static Fn2: any
66196619

66206620
def Bar()
6621-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(Fn))
6621+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn))
66226622
Fn = "abc"
66236623
assert_equal('string', typename(Fn))
66246624
Fn2 = Foo
6625-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(Fn2))
6625+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(Fn2))
66266626
Fn2 = "xyz"
66276627
assert_equal('string', typename(Fn2))
66286628
enddef
@@ -6639,7 +6639,7 @@ func Test_class_variable_complex_type_check()
66396639
" class variable with 'any" type. Can be assigned different types.
66406640
let lines =<< trim END
66416641
vim9script
6642-
def Foo(l: list<dict<number>>): dict<list<number>>
6642+
def Foo(l: list<dict<blob>>): dict<list<blob>>
66436643
return {}
66446644
enddef
66456645
class A
@@ -6648,11 +6648,11 @@ func Test_class_variable_complex_type_check()
66486648
endclass
66496649

66506650
def Bar()
6651-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(A.Fn))
6651+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn))
66526652
A.Fn = "abc"
66536653
assert_equal('string', typename(A.Fn))
66546654
A.Fn2 = Foo
6655-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(A.Fn2))
6655+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(A.Fn2))
66566656
A.Fn2 = "xyz"
66576657
assert_equal('string', typename(A.Fn2))
66586658
enddef
@@ -6662,6 +6662,19 @@ func Test_class_variable_complex_type_check()
66626662
Bar()
66636663
END
66646664
call v9.CheckSourceSuccess(lines)
6665+
6666+
let lines =<< trim END
6667+
vim9script
6668+
class A
6669+
public static foo = [0z10, 0z20]
6670+
endclass
6671+
assert_equal([0z10, 0z20], A.foo)
6672+
A.foo = [0z30]
6673+
assert_equal([0z30], A.foo)
6674+
var a = A.foo
6675+
assert_equal([0z30], a)
6676+
END
6677+
call v9.CheckSourceSuccess(lines)
66656678
endfunc
66666679

66676680
" Test type checking for object variable in assignments
@@ -6670,27 +6683,27 @@ func Test_object_variable_complex_type_check()
66706683
" script level.
66716684
let lines =<< trim END
66726685
vim9script
6673-
def Foo(l: list<dict<number>>): dict<list<number>>
6686+
def Foo(l: list<dict<blob>>): dict<list<blob>>
66746687
return {}
66756688
enddef
66766689
class A
6677-
public this.Fn: func(list<dict<number>>): dict<list<number>> = Foo
6690+
public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
66786691
endclass
66796692
var a = A.new()
66806693
test_garbagecollect_now()
66816694
a.Fn = "abc"
66826695
END
6683-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 10)
6696+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 10)
66846697

66856698
" object variable with a specific type. Try assigning a different type at
66866699
" object def method level.
66876700
let lines =<< trim END
66886701
vim9script
6689-
def Foo(l: list<dict<number>>): dict<list<number>>
6702+
def Foo(l: list<dict<blob>>): dict<list<blob>>
66906703
return {}
66916704
enddef
66926705
class A
6693-
public this.Fn: func(list<dict<number>>): dict<list<number>> = Foo
6706+
public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
66946707
def Bar()
66956708
this.Fn = "abc"
66966709
this.Fn = Foo
@@ -6700,17 +6713,17 @@ func Test_object_variable_complex_type_check()
67006713
test_garbagecollect_now()
67016714
a.Bar()
67026715
END
6703-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1)
6716+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
67046717

67056718
" object variable with a specific type. Try assigning a different type at
67066719
" script def method level.
67076720
let lines =<< trim END
67086721
vim9script
6709-
def Foo(l: list<dict<number>>): dict<list<number>>
6722+
def Foo(l: list<dict<blob>>): dict<list<blob>>
67106723
return {}
67116724
enddef
67126725
class A
6713-
public this.Fn: func(list<dict<number>>): dict<list<number>> = Foo
6726+
public this.Fn: func(list<dict<blob>>): dict<list<blob>> = Foo
67146727
endclass
67156728
def Bar()
67166729
var a = A.new()
@@ -6720,13 +6733,13 @@ func Test_object_variable_complex_type_check()
67206733
test_garbagecollect_now()
67216734
Bar()
67226735
END
6723-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 2)
6736+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 2)
67246737

67256738
" object variable without any type. Should be set to the initialization
67266739
" expression type. Try assigning a different type from script level.
67276740
let lines =<< trim END
67286741
vim9script
6729-
def Foo(l: list<dict<number>>): dict<list<number>>
6742+
def Foo(l: list<dict<blob>>): dict<list<blob>>
67306743
return {}
67316744
enddef
67326745
class A
@@ -6736,13 +6749,13 @@ func Test_object_variable_complex_type_check()
67366749
test_garbagecollect_now()
67376750
a.Fn = "abc"
67386751
END
6739-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 10)
6752+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 10)
67406753

67416754
" object variable without any type. Should be set to the initialization
67426755
" expression type. Try assigning a different type at object def level.
67436756
let lines =<< trim END
67446757
vim9script
6745-
def Foo(l: list<dict<number>>): dict<list<number>>
6758+
def Foo(l: list<dict<blob>>): dict<list<blob>>
67466759
return {}
67476760
enddef
67486761
class A
@@ -6756,13 +6769,13 @@ func Test_object_variable_complex_type_check()
67566769
test_garbagecollect_now()
67576770
a.Bar()
67586771
END
6759-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 1)
6772+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 1)
67606773

67616774
" object variable without any type. Should be set to the initialization
67626775
" expression type. Try assigning a different type at script def level.
67636776
let lines =<< trim END
67646777
vim9script
6765-
def Foo(l: list<dict<number>>): dict<list<number>>
6778+
def Foo(l: list<dict<blob>>): dict<list<blob>>
67666779
return {}
67676780
enddef
67686781
class A
@@ -6776,12 +6789,12 @@ func Test_object_variable_complex_type_check()
67766789
test_garbagecollect_now()
67776790
Bar()
67786791
END
6779-
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<number>>): dict<list<number>> but got string', 2)
6792+
call v9.CheckSourceFailure(lines, 'E1012: Type mismatch; expected func(list<dict<blob>>): dict<list<blob>> but got string', 2)
67806793

67816794
" object variable with 'any" type. Can be assigned different types.
67826795
let lines =<< trim END
67836796
vim9script
6784-
def Foo(l: list<dict<number>>): dict<list<number>>
6797+
def Foo(l: list<dict<blob>>): dict<list<blob>>
67856798
return {}
67866799
enddef
67876800
class A
@@ -6791,13 +6804,13 @@ func Test_object_variable_complex_type_check()
67916804

67926805
var a = A.new()
67936806
test_garbagecollect_now()
6794-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(a.Fn))
6807+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
67956808
a.Fn = "abc"
67966809
test_garbagecollect_now()
67976810
assert_equal('string', typename(a.Fn))
67986811
a.Fn2 = Foo
67996812
test_garbagecollect_now()
6800-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(a.Fn2))
6813+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
68016814
a.Fn2 = "xyz"
68026815
test_garbagecollect_now()
68036816
assert_equal('string', typename(a.Fn2))
@@ -6807,19 +6820,19 @@ func Test_object_variable_complex_type_check()
68076820
" object variable with 'any" type. Can be assigned different types.
68086821
let lines =<< trim END
68096822
vim9script
6810-
def Foo(l: list<dict<number>>): dict<list<number>>
6823+
def Foo(l: list<dict<blob>>): dict<list<blob>>
68116824
return {}
68126825
enddef
68136826
class A
68146827
public this.Fn: any = Foo
68156828
public this.Fn2: any
68166829

68176830
def Bar()
6818-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(this.Fn))
6831+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn))
68196832
this.Fn = "abc"
68206833
assert_equal('string', typename(this.Fn))
68216834
this.Fn2 = Foo
6822-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(this.Fn2))
6835+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(this.Fn2))
68236836
this.Fn2 = "xyz"
68246837
assert_equal('string', typename(this.Fn2))
68256838
enddef
@@ -6837,7 +6850,7 @@ func Test_object_variable_complex_type_check()
68376850
" object variable with 'any" type. Can be assigned different types.
68386851
let lines =<< trim END
68396852
vim9script
6840-
def Foo(l: list<dict<number>>): dict<list<number>>
6853+
def Foo(l: list<dict<blob>>): dict<list<blob>>
68416854
return {}
68426855
enddef
68436856
class A
@@ -6847,11 +6860,11 @@ func Test_object_variable_complex_type_check()
68476860

68486861
def Bar()
68496862
var a = A.new()
6850-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(a.Fn))
6863+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn))
68516864
a.Fn = "abc"
68526865
assert_equal('string', typename(a.Fn))
68536866
a.Fn2 = Foo
6854-
assert_equal('func(list<dict<number>>): dict<list<number>>', typename(a.Fn2))
6867+
assert_equal('func(list<dict<blob>>): dict<list<blob>>', typename(a.Fn2))
68556868
a.Fn2 = "xyz"
68566869
assert_equal('string', typename(a.Fn2))
68576870
enddef

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -704,6 +704,8 @@ static char *(features[]) =
704704

705705
static int included_patches[] =
706706
{ /* Add new patch number below this line */
707+
/**/
708+
1988,
707709
/**/
708710
1987,
709711
/**/

0 commit comments

Comments
 (0)