From: Christian Brabandt Date: Fri, 7 Aug 2026 20:22:20 +0000 (+0000) Subject: patch 9.2.0925: crash when getcompletiontype() gets a NULL string X-Git-Tag: v9.2.0925^0 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fheads%2Fmaster;p=thirdparty%2Fvim.git 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 --- diff --git a/src/cmdexpand.c b/src/cmdexpand.c index 34edf25ef0..98ce6259f5 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 a83dcb973c..68e66918cc 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 c0bd293658..4e1ff82f62 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, /**/