Commit: patch 9.1.1992: Vim9: heap buffer overflow with COMPAREANY instruction

2 views
Skip to first unread message

Christian Brabandt

unread,
Dec 17, 2025, 4:00:54 PM (10 hours ago) Dec 17
to vim...@googlegroups.com
patch 9.1.1992: Vim9: heap buffer overflow with COMPAREANY instruction

Commit: https://github.com/vim/vim/commit/b74c86416e256f126e12d75691c9163e9da62c85
Author: Foxe Chen <chen...@gmail.com>
Date: Wed Dec 17 21:47:53 2025 +0100

patch 9.1.1992: Vim9: heap buffer overflow with COMPAREANY instruction

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 <zeer...@outlook.com>
Signed-off-by: Foxe Chen <chen...@gmail.com>
Signed-off-by: Christian Brabandt <c...@256bit.org>

diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 099e343e8..8f55d88e2 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -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
diff --git a/runtime/doc/tags b/runtime/doc/tags
index 8b5d11a33..2f83c8a28 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -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*
diff --git a/src/errors.h b/src/errors.h
index 4ad8e14e8..67e88dba7 100644
--- a/src/errors.h
+++ b/src/errors.h
@@ -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[]
diff --git a/src/po/vim.pot b/src/po/vim.pot
index c76e8170e..42eb3b395 100644
--- a/src/po/vim.pot
+++ b/src/po/vim.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: Vim
"
"Report-Msgid-Bugs-To: vim...@vim.org
"
-"POT-Creation-Date: 2025-12-13 17:59+0100
"
+"POT-Creation-Date: 2025-12-17 21:42+0100
"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE
"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>
"
"Language-Team: LANGUAGE <L...@li.org>
"
@@ -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 ""
diff --git a/src/testdir/test_vim9_class.vim b/src/testdir/test_vim9_class.vim
index 467d0d1fc..6ec7ffa6e 100644
--- a/src/testdir/test_vim9_class.vim
+++ b/src/testdir/test_vim9_class.vim
@@ -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
diff --git a/src/typval.c b/src/typval.c
index 945f76320..bf8e9ab6c 100644
--- a/src/typval.c
+++ b/src/typval.c
@@ -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;
diff --git a/src/version.c b/src/version.c
index b18869873..80384a0fb 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
+/**/
+ 1992,
/**/
1991,
/**/
Reply all
Reply to author
Forward
0 new messages