0
0
mirror of https://github.com/vim/vim.git synced 2025-07-04 23:07:33 -04:00

patch 9.1.0385: Vim9: crash with null_class and null_object

Problem:  Vim9: crash with null_class and null_object
          (Aliaksei Budavei)
Solution: Handle null_class and null_object correctly
          (Yegappan Lakshmanan)

fixes: #14678
closes: #14681

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
This commit is contained in:
Yegappan Lakshmanan 2024-05-01 11:44:17 +02:00 committed by Christian Brabandt
parent ca4b81a7ae
commit b2e42b9be0
No known key found for this signature in database
GPG Key ID: F3F92DA383FDDE09
5 changed files with 67 additions and 10 deletions

View File

@ -6403,9 +6403,9 @@ echo_string_core(
{ {
class_T *cl = tv->vval.v_class; class_T *cl = tv->vval.v_class;
char *s = "class"; char *s = "class";
if (IS_INTERFACE(cl)) if (cl && IS_INTERFACE(cl))
s = "interface"; s = "interface";
else if (IS_ENUM(cl)) else if (cl && IS_ENUM(cl))
s = "enum"; s = "enum";
size_t len = STRLEN(s) + 1 + size_t len = STRLEN(s) + 1 +
(cl == NULL ? 9 : STRLEN(cl->class_name)) + 1; (cl == NULL ? 9 : STRLEN(cl->class_name)) + 1;

View File

@ -11497,7 +11497,7 @@ f_type(typval_T *argvars, typval_T *rettv)
case VAR_CLASS: case VAR_CLASS:
{ {
class_T *cl = argvars[0].vval.v_class; class_T *cl = argvars[0].vval.v_class;
if (IS_ENUM(cl)) if (cl && IS_ENUM(cl))
n = VAR_TYPE_ENUM; n = VAR_TYPE_ENUM;
else else
n = VAR_TYPE_CLASS; n = VAR_TYPE_CLASS;
@ -11505,11 +11505,18 @@ f_type(typval_T *argvars, typval_T *rettv)
} }
case VAR_OBJECT: case VAR_OBJECT:
{ {
class_T *cl = argvars[0].vval.v_object->obj_class; object_T *obj = argvars[0].vval.v_object;
if (IS_ENUM(cl))
n = VAR_TYPE_ENUMVALUE; if (obj == NULL)
else
n = VAR_TYPE_OBJECT; n = VAR_TYPE_OBJECT;
else
{
class_T *cl = argvars[0].vval.v_object->obj_class;
if (IS_ENUM(cl))
n = VAR_TYPE_ENUMVALUE;
else
n = VAR_TYPE_OBJECT;
}
break; break;
} }
case VAR_UNKNOWN: case VAR_UNKNOWN:

View File

@ -545,6 +545,52 @@ def Test_using_null_class()
@_ = null_class.member @_ = null_class.member
END END
v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type']) v9.CheckDefExecAndScriptFailure(lines, ['E715: Dictionary required', 'E1363: Incomplete type'])
# Test for using a null class as a value
lines =<< trim END
vim9script
echo empty(null_class)
END
v9.CheckSourceFailure(lines, 'E1405: Class "" cannot be used as a value', 2)
# Test for using a null class with string()
lines =<< trim END
vim9script
assert_equal('class [unknown]', string(null_class))
END
v9.CheckSourceSuccess(lines)
# Test for using a null class with string()
lines =<< trim END
vim9script
assert_equal(12, type(null_class))
assert_equal('class<Unknown>', typename(null_class))
END
v9.CheckSourceSuccess(lines)
enddef
def Test_using_null_object()
# Test for using a null object as a value
var lines =<< trim END
vim9script
assert_equal(1, empty(null_object))
END
v9.CheckSourceSuccess(lines)
# Test for using a null object with string()
lines =<< trim END
vim9script
assert_equal('object of [unknown]', string(null_object))
END
v9.CheckSourceSuccess(lines)
# Test for using a null object with string()
lines =<< trim END
vim9script
assert_equal(13, type(null_object))
assert_equal('object<Unknown>', typename(null_object))
END
v9.CheckSourceSuccess(lines)
enddef enddef
def Test_class_interface_wrong_end() def Test_class_interface_wrong_end()

View File

@ -704,6 +704,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
385,
/**/ /**/
384, 384,
/**/ /**/

View File

@ -2091,10 +2091,12 @@ check_typval_is_value(typval_T *tv)
case VAR_CLASS: case VAR_CLASS:
{ {
class_T *cl = tv->vval.v_class; class_T *cl = tv->vval.v_class;
if (IS_ENUM(cl)) char_u *class_name = (cl == NULL) ? (char_u *)""
semsg(_(e_using_enum_as_value_str), cl->class_name); : cl->class_name;
if (cl && IS_ENUM(cl))
semsg(_(e_using_enum_as_value_str), class_name);
else else
semsg(_(e_using_class_as_value_str), cl->class_name); semsg(_(e_using_class_as_value_str), class_name);
} }
return FAIL; return FAIL;