Commit: patch 9.2.0925: crash when getcompletiontype() gets a NULL string

Christian Brabandt <[email protected]> Fri, 7 Aug 2026 22:30:07 +0200
Newsgroups gmane.editors.vim.devel
Message-ID <[email protected]>
patch 9.2.0925: crash when getcompletiontype() gets a NULL string

Commit: https://github.com/vim/vim/commit/e2dcefa0d8c03a7d2ebda67207e3d1392ae0c402
Author: Christian Brabandt <[email protected]>
Date:   Fri Aug 7 20:22:20 2026 +0000

    patch 9.2.0925: crash when getcompletiontype() gets a NULL string
    
    Problem:  Crash when getcompletiontype()/getcompletion() gets a NULL string
              (dvaave2025).
    Solution: Do not write the NUL terminator in set_cmd_context() when the
              cursor column is at or past the end of the string, since the
              string may be a read-only literal.
    
    fixes:  #20963
    closes: #20964
    
    Supported by AI.
    
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/src/cmdexpand.c b/src/cmdexpand.c
index 34edf25ef..98ce6259f 100644
--- a/src/cmdexpand.c
+++ b/src/cmdexpand.c
@@ -3133,11 +3133,16 @@ set_cmd_context(
     int		old_char = NUL;
     char_u	*nextcomm;
 
-    // Avoid a UMR warning from Purify, only save the character if it has been
-    // written before.
+    // Only save and overwrite the character when it is not the NUL terminator
+    // already.  "str" may be a read-only empty string: tv_get_string() falls
+    // back to a "" literal for a NULL string or on a type error, and writing
+    // at "col" would then crash.
+    // This also avoids a UMR warning from Purify.
     if (col < len)
+    {
 	old_char = str[col];
-    str[col] = NUL;
+	str[col] = NUL;
+    }
     nextcomm = str;
 
 #ifdef FEAT_EVAL
@@ -3168,7 +3173,8 @@ set_cmd_context(
     xp->xp_line = str;
     xp->xp_col = col;
 
-    str[col] = old_char;
+    if (col < len)
+	str[col] = old_char;
 }
 
 /*
diff --git a/src/testdir/test_cmdline.vim b/src/testdir/test_cmdline.vim
index a83dcb973..68e66918c 100644
--- a/src/testdir/test_cmdline.vim
+++ b/src/testdir/test_cmdline.vim
@@ -1024,6 +1024,11 @@ func Test_getcompletiontype()
   call assert_equal('var', getcompletiontype('let v:n'))
   call assert_equal('function', getcompletiontype('call tag'))
   call assert_equal('help', getcompletiontype('help '))
+  " must not write into a read-only empty string
+  call assert_equal('command', getcompletiontype(test_null_string()))
+  call assert_equal(getcompletion('', 'cmdline'),
+    \ getcompletion(test_null_string(), 'cmdline'))
+  call assert_fails('call getcompletion([], "cmdline")', 'E730:')
 endfunc
 
 func Test_multibyte_expression()
diff --git a/src/version.c b/src/version.c
index c0bd29365..4e1ff82f6 100644
--- a/src/version.c
+++ b/src/version.c
@@ -763,6 +763,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    925,
 /**/
     924,
 /**/

-- 
-- 
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/E1wsRCh-000jBc-4f%40256bit.org.