From b74c86416e256f126e12d75691c9163e9da62c85 Mon Sep 17 00:00:00 2001 From: Foxe Chen Date: Wed, 17 Dec 2025 21:47:53 +0100 Subject: [PATCH] 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 Signed-off-by: Foxe Chen Signed-off-by: Christian Brabandt --- runtime/doc/eval.txt | 10 ++++++++-- runtime/doc/tags | 1 + src/errors.h | 4 +++- src/po/vim.pot | 13 +++++-------- src/testdir/test_vim9_class.vim | 23 +++++++++++++++++++++++ src/typval.c | 5 +++++ src/version.c | 2 ++ 7 files changed, 47 insertions(+), 11 deletions(-) diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt index 099e343e89..8f55d88e21 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 8b5d11a338..2f83c8a28d 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 4ad8e14e8e..67e88dba79 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 c76e8170e3..42eb3b395c 100644 --- a/src/po/vim.pot +++ b/src/po/vim.pot @@ -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 \n" "Language-Team: LANGUAGE \n" @@ -3582,16 +3582,10 @@ msgstr "" msgid "Sponsor Vim development!" msgstr "" -msgid "Become a registered Vim user!" -msgstr "" - msgid "type :help sponsor for information " msgstr "" -msgid "type :help register 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 467d0d1fcf..6ec7ffa6e2 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 but got dict', 'E1012: Type mismatch; expected object but got dict']) + + # Error if comparing object with non object when using COMPAREANY instruction + lines =<< trim END + vim9script + + enum DirectiveType + Unknown, + Set + endenum + + type PatternSteps = list + type Directive = tuple + + 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 945f763207..bf8e9ab6ca 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 b188698732..80384a0fb1 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, /**/ -- 2.47.3