]> git.ipfire.org Git - thirdparty/vim.git/commitdiff
patch 9.2.0925: crash when getcompletiontype() gets a NULL string v9.2.0925
authorChristian Brabandt <cb@256bit.org>
Fri, 7 Aug 2026 20:22:20 +0000 (20:22 +0000)
committerChristian Brabandt <cb@256bit.org>
Fri, 7 Aug 2026 20:22:20 +0000 (20:22 +0000)
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 <cb@256bit.org>
src/cmdexpand.c
src/testdir/test_cmdline.vim
src/version.c

index 34edf25ef0113ac491bb42f8830072b3f8ba7da0..98ce6259f5dcc5a71fbb381ea7dcf2ff6c863d57 100644 (file)
@@ -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;
 }
 
 /*
index a83dcb973c002bf3a88a65088e68cdb6b63d04bf..68e66918cc89de53dca44c0f91f18eb36f9ebcb4 100644 (file)
@@ -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()
index c0bd2936584ea259ac03d288a5d1a704799504fc..4e1ff82f62abbdddec37794207e08aa8659d2e31 100644 (file)
@@ -763,6 +763,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    925,
 /**/
     924,
 /**/