]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.0385: Vim9: crash with null_class and null_object v9.1.0385
authorYegappan Lakshmanan <yegappan@yahoo.com>
Wed, 1 May 2024 09:44:17 +0000 (11:44 +0200)
committerChristian Brabandt <cb@256bit.org>
Wed, 1 May 2024 09:44:17 +0000 (11:44 +0200)
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>
src/eval.c
src/evalfunc.c
src/testdir/test_vim9_class.vim
src/version.c
src/vim9type.c

index 51ee6043196fa6c213c7ae091d3d626e41ff8968..21ba1bcfcde37c4d83b5f754a049fbc23552c06c 100644 (file)
@@ -6403,9 +6403,9 @@ echo_string_core(
            {
                class_T *cl = tv->vval.v_class;
                char *s = "class";
-               if (IS_INTERFACE(cl))
+               if (cl && IS_INTERFACE(cl))
                    s = "interface";
-               else if (IS_ENUM(cl))
+               else if (cl && IS_ENUM(cl))
                    s = "enum";
                size_t len = STRLEN(s) + 1 +
                    (cl == NULL ? 9 : STRLEN(cl->class_name)) + 1;
index 20649828e02a23f668880fb9c5bace03948f91dd..742c5f8e79a5f0ee0d04f930b7c46a694cec1bf7 100644 (file)
@@ -11497,7 +11497,7 @@ f_type(typval_T *argvars, typval_T *rettv)
        case VAR_CLASS:
            {
                class_T *cl = argvars[0].vval.v_class;
-               if (IS_ENUM(cl))
+               if (cl && IS_ENUM(cl))
                    n = VAR_TYPE_ENUM;
                else
                    n = VAR_TYPE_CLASS;
@@ -11505,11 +11505,18 @@ f_type(typval_T *argvars, typval_T *rettv)
            }
        case VAR_OBJECT:
            {
-               class_T *cl = argvars[0].vval.v_object->obj_class;
-               if (IS_ENUM(cl))
-                   n = VAR_TYPE_ENUMVALUE;
-               else
+               object_T *obj = argvars[0].vval.v_object;
+
+               if (obj == NULL)
                    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;
            }
        case VAR_UNKNOWN:
index ed3aac0be2978a1b70b92d1cc039321e40a107ed..0a48b822df0d6d4b8c5d0a41159804e587c92b37 100644 (file)
@@ -545,6 +545,52 @@ def Test_using_null_class()
     @_ = null_class.member
   END
   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
 
 def Test_class_interface_wrong_end()
index 739f01fc42daff07eeb7d68e97f8ffe69b0591bd..183c388ef7304ba043a94b4a2c6c126559af3f3a 100644 (file)
@@ -704,6 +704,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    385,
 /**/
     384,
 /**/
index 775291e7436e2898ec2b052f64d6c25fb8f2c510..ab7efce7a04b56a1bc8480b7f476b2ff00fd5486 100644 (file)
@@ -2091,10 +2091,12 @@ check_typval_is_value(typval_T *tv)
        case VAR_CLASS:
            {
                class_T *cl = tv->vval.v_class;
-               if (IS_ENUM(cl))
-                   semsg(_(e_using_enum_as_value_str), cl->class_name);
+               char_u *class_name = (cl == NULL) ? (char_u *)""
+                                                       : cl->class_name;
+               if (cl && IS_ENUM(cl))
+                   semsg(_(e_using_enum_as_value_str), class_name);
                else
-                   semsg(_(e_using_class_as_value_str), cl->class_name);
+                   semsg(_(e_using_class_as_value_str), class_name);
            }
            return FAIL;