patch 9.1.1766: Vim9: some functions do not handle null_string correctly

Commit: 
https://github.com/vim/vim/commit/afa2a81a88d123d4c39a75bddfc41559b81188b2
Author: Yegappan Lakshmanan <[email protected]>
Date:   Tue Sep 16 19:19:42 2025 +0000

    patch 9.1.1766: Vim9: some functions do not handle null_string correctly
    
    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 <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/testdir/test_vim9_builtin.vim 
b/src/testdir/test_vim9_builtin.vim
index 8b84a47ec..1cf4010cd 100644
--- a/src/testdir/test_vim9_builtin.vim
+++ b/src/testdir/test_vim9_builtin.vim
@@ -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()
diff --git a/src/version.c b/src/version.c
index f58befda0..8be4f5f84 100644
--- a/src/version.c
+++ b/src/version.c
@@ -724,6 +724,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1766,
 /**/
     1765,
 /**/
diff --git a/src/vim9expr.c b/src/vim9expr.c
index f3aa4b1f5..375986cb7 100644
--- a/src/vim9expr.c
+++ b/src/vim9expr.c
@@ -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);
        }
 

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1uybNN-00AfaX-A4%40256bit.org.

Raspunde prin e-mail lui