Skip to content

Commit d7085a0

Browse files
mg979chrisbra
authored andcommitted
patch 9.0.1830: Vim9: crash when accessing a null object
Problem: Vim9: crash when accessing a null object Solution: Check accessing a NULL object in def function An object is NULL when the variable is declared, but the constructor isn't called. Accessing/setting a member on the object crashed Vim. Note: this happens inside def functions, at script level things work differently. Accessing a NULL object member results in E1360 (correctly), while setting a value on it results in E1012 (type mismatch) so there's still something to fix. closes: #12973 Signed-off-by: Christian Brabandt <[email protected]> Co-authored-by: Gianmaria Bajo <[email protected]>
1 parent eb91e24 commit d7085a0

3 files changed

Lines changed: 65 additions & 1 deletion

File tree

src/testdir/test_vim9_class.vim

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,6 +1180,61 @@ def Test_class_member()
11801180
END
11811181
v9.CheckScriptFailure(lines, 'E1010:')
11821182

1183+
# Test for setting a member on a null object
1184+
lines =<< trim END
1185+
vim9script
1186+
class A
1187+
this.val: string
1188+
endclass
1189+
1190+
def F()
1191+
var obj: A
1192+
obj.val = ""
1193+
enddef
1194+
F()
1195+
END
1196+
v9.CheckScriptFailure(lines, 'E1360: Using a null object')
1197+
1198+
# Test for accessing a member on a null object
1199+
lines =<< trim END
1200+
vim9script
1201+
class A
1202+
this.val: string
1203+
endclass
1204+
1205+
def F()
1206+
var obj: A
1207+
echo obj.val
1208+
enddef
1209+
F()
1210+
END
1211+
v9.CheckScriptFailure(lines, 'E1360: Using a null object')
1212+
1213+
# Test for setting a member on a null object, at script level
1214+
lines =<< trim END
1215+
vim9script
1216+
class A
1217+
this.val: string
1218+
endclass
1219+
1220+
var obj: A
1221+
obj.val = ""
1222+
END
1223+
# FIXME(in source): this should give E1360 as well!
1224+
v9.CheckScriptFailure(lines, 'E1012: Type mismatch; expected object<A> but got string')
1225+
1226+
# Test for accessing a member on a null object, at script level
1227+
lines =<< trim END
1228+
vim9script
1229+
class A
1230+
this.val: string
1231+
endclass
1232+
1233+
var obj: A
1234+
echo obj.val
1235+
END
1236+
v9.CheckScriptFailure(lines, 'E1360: Using a null object')
1237+
11831238
# Test for no space before or after the '=' when initializing a member
11841239
# variable
11851240
lines =<< trim END

src/version.c

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

700700
static int included_patches[] =
701701
{ /* Add new patch number below this line */
702+
/**/
703+
1830,
702704
/**/
703705
1829,
704706
/**/

src/vim9execute.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2147,7 +2147,14 @@ execute_storeindex(isn_T *iptr, ectx_T *ectx)
21472147
// -1 dict, list, blob or object
21482148
tv = STACK_TV_BOT(-3);
21492149
SOURCING_LNUM = iptr->isn_lnum;
2150-
if (dest_type == VAR_ANY)
2150+
2151+
// Make sure an object has been initialized
2152+
if (dest_type == VAR_OBJECT && tv_dest->vval.v_object == NULL)
2153+
{
2154+
emsg(_(e_using_null_object));
2155+
status = FAIL;
2156+
}
2157+
else if (dest_type == VAR_ANY)
21512158
{
21522159
dest_type = tv_dest->v_type;
21532160
if (dest_type == VAR_DICT)

0 commit comments

Comments
 (0)