]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.1.1766: Vim9: some functions do not handle null_string correctly v9.1.1766
authorYegappan Lakshmanan <yegappan@yahoo.com>
Tue, 16 Sep 2025 19:19:42 +0000 (19:19 +0000)
committerChristian Brabandt <cb@256bit.org>
Tue, 16 Sep 2025 19:19:42 +0000 (19:19 +0000)
Problem:  Vim9: some Vim9 functions do not handle null_string correctly
          and may crash Vim (kennypete).
Solution: Check for null_string correctly in the searchpair() and
          substitute() functions (Yegappan Lakshmanan).

fixes: #18309
closes: #18311

Signed-off-by: Yegappan Lakshmanan <yegappan@yahoo.com>
Signed-off-by: Christian Brabandt <cb@256bit.org>
src/testdir/test_vim9_builtin.vim
src/version.c
src/vim9expr.c

index 8b84a47eca23140cdd6d159900e899b295909d19..1cf4010cd850d20fd9a4ee0ba4526793a691f89a 100644 (file)
@@ -3875,6 +3875,26 @@ def Test_searchpair()
   errors = ['E1013: Argument 7: type mismatch, expected number but got string', 'E1210: Number required for argument 7']
   v9.CheckSourceDefAndScriptFailure(['searchpair("a", "b", "c", "r", "1", 3, "g")'], errors)
   v9.CheckSourceDefAndScriptFailure(['searchpairpos("a", "b", "c", "r", "1", 3, "g")'], errors)
+
+  # calling searchpair() with null_string arguments
+  lines =<< trim END
+    new
+    setline(1, ['{', '', '}'])
+
+    cursor(1, 1)
+    searchpair('{', '', '}', '', null_string)
+    assert_equal(3, line('.'))
+
+    cursor(1, 1)
+    searchpair('{', '', '}', null_string, null_string)
+    assert_equal(3, line('.'))
+
+    cursor(1, 1)
+    searchpair(null_string, null_string, null_string, null_string, null_string)
+    assert_equal(1, line('.'))
+    bw!
+  END
+  v9.CheckSourceDefAndScriptSuccess(lines)
 enddef
 
 def Test_searchpos()
@@ -4538,6 +4558,27 @@ def Test_substitute()
     assert_equal("4", substitute("3", '\d', '\="text" x', 'g'))
   END
   v9.CheckSourceDefAndScriptFailure(lines, 'E488: Trailing characters: x')
+
+  # check for using null_string as argument to substitute()
+  lines =<< trim END
+    assert_equal('Vim', 'Vimp'->substitute('p', '', null_string))
+    assert_equal('Vim', 'Vimp'->substitute('p', null_string, null_string))
+    assert_equal('Vimp', 'Vimp'->substitute(null_string, null_string, null_string))
+    assert_equal('', substitute(null_string, null_string, null_string, null_string))
+  END
+  v9.CheckSourceDefAndScriptSuccess(lines)
+
+  # lambda function calling substitute() with null_string arguments
+  lines =<< trim END
+    const Subst_Fn: func = (a: string, b: string, c: string, d: string): string => {
+      return a->substitute(b, c, d)
+    }
+    assert_equal('Vim', Subst_Fn('Vimp', 'p', '', null_string))
+    assert_equal('Vim', Subst_Fn('Vimp', 'p', null_string, null_string))
+    assert_equal('Vimp', Subst_Fn('Vimp', null_string, null_string, null_string))
+    assert_equal('', Subst_Fn(null_string, null_string, null_string, null_string))
+  END
+  v9.CheckSourceDefAndScriptSuccess(lines)
 enddef
 
 def Test_swapinfo()
index f58befda0024fc69229b3b0dbc773472cb255b2b..8be4f5f84870bd6851ebe62be82daaeac1e5eeca 100644 (file)
@@ -724,6 +724,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1766,
 /**/
     1765,
 /**/
index f3aa4b1f5cef4e4bee2098e65111b7bfa28401df..375986cb7e2a362ee000db792e33ada241a98912 100644 (file)
@@ -1199,7 +1199,9 @@ compile_arguments(
            isn_T *isn = ((isn_T *)cctx->ctx_instr.ga_data) + instr_count;
 
            // {skip} argument of searchpair() can be compiled if not empty
-           if (isn->isn_type == ISN_PUSHS && *isn->isn_arg.string != NUL)
+           if (isn->isn_type == ISN_PUSHS
+                   && isn->isn_arg.string != NULL
+                   && *isn->isn_arg.string != NUL)
                compile_string(isn, cctx, 0);
        }
        else if (special_fn == CA_SUBSTITUTE && *argcount == 3
@@ -1209,8 +1211,10 @@ compile_arguments(
 
            // {sub} argument of substitute() can be compiled if it starts
            // with \=
-           if (isn->isn_type == ISN_PUSHS && isn->isn_arg.string[0] == '\\'
-                                             && isn->isn_arg.string[1] == '=')
+           if (isn->isn_type == ISN_PUSHS
+                   && isn->isn_arg.string != NULL
+                   && isn->isn_arg.string[0] == '\\'
+                   && isn->isn_arg.string[1] == '=')
                compile_string(isn, cctx, 2);
        }