]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1992: Vim9: heap buffer overflow with COMPAREANY instruction v9.1.1992
authorFoxe Chen <chen.foxe@gmail.com>
Wed, 17 Dec 2025 20:47:53 +0000 (21:47 +0100)
committerChristian Brabandt <cb@256bit.org>
Wed, 17 Dec 2025 20:47:53 +0000 (21:47 +0100)
Problem:  Vim9: heap buffer overflow with COMPAREANY instruction
Solution: Verify the type and error out in case of different types
          (Foxe Chen)

closes: #18945

Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Signed-off-by: Foxe Chen <chen.foxe@gmail.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
runtime/doc/eval.txt
runtime/doc/tags
src/errors.h
src/po/vim.pot
src/testdir/test_vim9_class.vim
src/typval.c
src/version.c

index 099e343e898557f70bc138cb94945bace8fb8b25..8f55d88e21fc5a84fbec140a984cfed0592c055a 100644 (file)
@@ -1,4 +1,4 @@
-*eval.txt*     For Vim version 9.1.  Last change: 2025 Dec 13
+*eval.txt*     For Vim version 9.1.  Last change: 2025 Dec 17
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -1349,7 +1349,13 @@ To compare Funcrefs to see if they refer to the same function, ignoring bound
 Dictionary and arguments, use |get()| to get the function name: >
        if get(Part1, 'name') == get(Part2, 'name')
           " Part1 and Part2 refer to the same function
-<                                                      *E1037*
+<
+                                                       *E1437*
+An |Object| can only be compared with another |Object|, using only the
+"equal", "not equal", "is" and "isnot" operators |expr4|.  An |Enum| is also a
+type of |Object|, and the same rules apply.
+
+                                                       *E1037*
 Using "is" or "isnot" with a |List|, |Tuple|, |Dictionary| or |Blob| checks
 whether the expressions are referring to the same |List|, |Tuple|,
 |Dictionary| or |Blob| instance.  A copy of a |List| or |Tuple| is different
index 8b5d11a33823d9b53d05c6864f4cb53c980d0d3a..2f83c8a28dde150f720dfa286c68ee74db426c2f 100644 (file)
@@ -4670,6 +4670,7 @@ E1433     vim9.txt        /*E1433*
 E1434  vim9.txt        /*E1434*
 E1435  vim9class.txt   /*E1435*
 E1436  vim9class.txt   /*E1436*
+E1437  eval.txt        /*E1437*
 E144   various.txt     /*E144*
 E145   starting.txt    /*E145*
 E146   change.txt      /*E146*
index 4ad8e14e8e0ae67ba52a6ea4fe58c7d617e9c4e2..67e88dba794744063de7b77903e2a5a09163e0a1 100644 (file)
@@ -3631,8 +3631,10 @@ EXTERN char e_enum_can_only_be_used_in_script[]
        INIT(= N_("E1435: Enum can only be used in a script"));
 EXTERN char e_interface_can_only_be_used_in_script[]
        INIT(= N_("E1436: Interface can only be used in a script"));
+EXTERN char e_can_only_compare_object_with_object[]
+       INIT(= N_("E1437: Can only compare Object with Object"));
 #endif
-// E1437 - E1499 unused (reserved for Vim9 class support)
+// E1438 - E1499 unused (reserved for Vim9 class support)
 EXTERN char e_cannot_mix_positional_and_non_positional_str[]
        INIT(= N_("E1500: Cannot mix positional and non-positional arguments: %s"));
 EXTERN char e_fmt_arg_nr_unused_str[]
index c76e8170e3078788f7eb6e2e37a4a9995b9e059c..42eb3b395c7ae778951c9f4ae68bd4426e2d0a17 100644 (file)
@@ -8,7 +8,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: Vim\n"
 "Report-Msgid-Bugs-To: vim-dev@vim.org\n"
-"POT-Creation-Date: 2025-12-13 17:59+0100\n"
+"POT-Creation-Date: 2025-12-17 21:42+0100\n"
 "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
 "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -3582,16 +3582,10 @@ msgstr ""
 msgid "Sponsor Vim development!"
 msgstr ""
 
-msgid "Become a registered Vim user!"
-msgstr ""
-
 msgid "type  :help sponsor<Enter>    for information "
 msgstr ""
 
-msgid "type  :help register<Enter>   for information "
-msgstr ""
-
-msgid "menu  Help->Sponsor/Register  for information    "
+msgid "menu  Help->Sponsor  for information    "
 msgstr ""
 
 msgid "global"
@@ -8593,6 +8587,9 @@ msgstr ""
 msgid "E1436: Interface can only be used in a script"
 msgstr ""
 
+msgid "E1437: Can only compare Object with Object"
+msgstr ""
+
 #, c-format
 msgid "E1500: Cannot mix positional and non-positional arguments: %s"
 msgstr ""
index 467d0d1fcff5a5a8d0ef380bd0e3e4c987f2e2f5..6ec7ffa6e232288474f13a3d76c5e810f79be6b8 100644 (file)
@@ -13008,6 +13008,29 @@ def Test_object_any_type()
     x['a'] = {}
   END
   v9.CheckSourceDefAndScriptFailure(lines, ['E1012: Type mismatch; expected object<any> but got dict<any>', 'E1012: Type mismatch; expected object<any> but got dict<any>'])
+
+  # Error if comparing object with non object when using COMPAREANY instruction
+  lines =<< trim END
+    vim9script
+
+    enum DirectiveType
+        Unknown,
+        Set
+    endenum
+
+    type PatternSteps = list<any>
+    type Directive = tuple<DirectiveType, PatternSteps>
+
+    def Test(): void
+        var directive: Directive = (DirectiveType.Unknown, ["eq", 1, "hello"])
+
+        if directive[0] == "test"
+        endif
+    enddef
+
+    Test()
+  END
+  v9.CheckSourceFailure(lines, 'E1437: Can only compare Object with Object', 3)
 enddef
 
 " Test for object<{class}> type
index 945f7632078360d9acf21edbe7f7845c3d818532..bf8e9ab6caab1d0bbe2865293f2313b1b8e8298c 100644 (file)
@@ -1887,6 +1887,11 @@ typval_compare_object(
        *res = obj1 == obj2 ? res_match : !res_match;
        return OK;
     }
+    else if (tv1->v_type != tv2->v_type)
+    {
+       emsg(_(e_can_only_compare_object_with_object));
+       return FAIL;
+    }
 
     *res = object_equal(obj1, obj2, ic) ? res_match : !res_match;
     return OK;
index b18869873204976b63cce04166a591959aa70c9e..80384a0fb194aae870fd3643b4a0402dc48c4fa0 100644 (file)
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1992,
 /**/
     1991,
 /**/