diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 956394db1b..533fa95e99 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1593,12 +1593,13 @@ static void init_prompt(int cmdchar_todo) char *prompt = prompt_text(); int prompt_len = (int)strlen(prompt); - if (curwin->w_cursor.lnum < curbuf->b_prompt_start.mark.lnum) { - curwin->w_cursor.lnum = curbuf->b_prompt_start.mark.lnum; - } + curwin->w_cursor.lnum = MAX(curwin->w_cursor.lnum, curbuf->b_prompt_start.mark.lnum); char *text = ml_get(curbuf->b_prompt_start.mark.lnum); + colnr_T text_len = ml_get_len(curbuf->b_prompt_start.mark.lnum); + if ((curbuf->b_prompt_start.mark.lnum == curwin->w_cursor.lnum && (curbuf->b_prompt_start.mark.col < prompt_len + || curbuf->b_prompt_start.mark.col > text_len || !strnequal(text + curbuf->b_prompt_start.mark.col - prompt_len, prompt, (size_t)prompt_len)))) { // prompt is missing, insert it or append a line with it diff --git a/src/nvim/eval/buffer.c b/src/nvim/eval/buffer.c index 117acdcf5e..813d839dfe 100644 --- a/src/nvim/eval/buffer.c +++ b/src/nvim/eval/buffer.c @@ -778,12 +778,13 @@ void f_prompt_setprompt(typval_T *argvars, typval_T *rettv, EvalFuncData fptr) linenr_T prompt_lno = buf->b_prompt_start.mark.lnum; char *old_prompt = buf_prompt_text(buf); char *old_line = ml_get_buf(buf, prompt_lno); - old_line = old_line != NULL ? old_line : ""; + colnr_T old_line_len = ml_get_buf_len(buf, prompt_lno); int old_prompt_len = (int)strlen(old_prompt); colnr_T cursor_col = curwin->w_cursor.col; if (buf->b_prompt_start.mark.col < old_prompt_len + || buf->b_prompt_start.mark.col > old_line_len || !strnequal(old_prompt, old_line + buf->b_prompt_start.mark.col - old_prompt_len, (size_t)old_prompt_len)) { // If for some odd reason the old prompt is missing, diff --git a/test/functional/legacy/prompt_buffer_spec.lua b/test/functional/legacy/prompt_buffer_spec.lua index 83825c8a94..1acc6a2258 100644 --- a/test/functional/legacy/prompt_buffer_spec.lua +++ b/test/functional/legacy/prompt_buffer_spec.lua @@ -667,6 +667,10 @@ describe('prompt buffer', function() eq({ last_line, 6 }, api.nvim_buf_get_mark(0, ':')) eq(true, api.nvim_buf_set_mark(0, ':', 1, 5, {})) eq({ 1, 5 }, api.nvim_buf_get_mark(0, ':')) + + -- No crash from invalid col. + eq(true, api.nvim_buf_set_mark(0, ':', fn('line', '.'), 999, {})) + eq({ 12, 6 }, api.nvim_buf_get_mark(0, ':')) end) describe('prompt_getinput', function() @@ -861,5 +865,17 @@ describe('prompt buffer', function() {1:~ }|*3 {5:-- INSERT --} | ]]) + + -- No prompt_setprompt crash from invalid ': col. Must happen in the same event. + exec_lua(function() + vim.cmd 'bwipeout!' + vim.api.nvim_buf_set_mark(0, ':', vim.fn.line('.'), 999, {}) + vim.fn.prompt_setprompt('', 'new-prompt > ') + end) + screen:expect([[ + new-prompt > ^ | + {1:~ }|*8 + {5:-- INSERT --} | + ]]) end) end)