diff options
author | Alexandre Teoi <ateoi@users.noreply.github.com> | 2023-07-01 10:33:51 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-01 06:33:51 -0700 |
commit | a741c7fd0465c949a0016fcbee5f4526b65f8c02 (patch) | |
tree | a4ce55f6a9a1fdb11a11c5642e5d74e775315ee5 /src/nvim/ex_getln.c | |
parent | 43ded8d3584477ab14731486cfb0e86534f2b2dc (diff) | |
download | rneovim-a741c7fd0465c949a0016fcbee5f4526b65f8c02.tar.gz rneovim-a741c7fd0465c949a0016fcbee5f4526b65f8c02.tar.bz2 rneovim-a741c7fd0465c949a0016fcbee5f4526b65f8c02.zip |
fix(api): nvim_parse_cmd error message in pcall() #23297
Problem:
nvim_parse_cmd() in pcall() may show an error message (side-effect):
:lua pcall(vim.api.nvim_parse_cmd, vim.fn.getcmdline(), {})
E16: Invalid range
Solution:
Avoid emsg() in the nvim_parse_cmd() codepath.
- refactor(api): add error message output parameter to get_address()
- fix: null check emsg() parameter
- refactor: remove emsg_off workaround from do_incsearch_highlighting()
- refactor: remove emsg_off workaround from cmdpreview_may_show()
- refactor: remove remaining calls to emsg() from parse_cmd_address() and get_address()
- (refactor): lint set_cmd_dflall_range()
- refactor: addr_error() - move output parameter to return value
Fix #20339
TODO:
These are the functions called by `get_address()`:
```
nvim_parse_cmd() -> parse_cmdline() -> parse_cmd_address() -> get_address()
skipwhite()
addr_error()
qf_get_cur_idx()
qf_get_cur_valid_idx()
qf_get_size()
qf_get_valid_size()
mark_get()
mark_check()
assert()
skip_regexp()
magic_isset()
> do_search()
> searchit()
ascii_isdigit()
getdigits()
getdigits_int32()
compute_buffer_local_count()
hasFolding()
```
From these functions, I found at least two that call emsg directly:
- do_search()
- seems to be simple to refactor
- searchit()
- will be more challenging because it may generate multiple error messages,
which can't be handled by the current `errormsg` out-parameter.
For example, it makes multiple calls to `vim_regexec_multi()` in a loop that
possibly generate error messages, and later `searchit()` itself may generate
another one:
- https://github.com/neovim/neovim/blob/c194acbfc479d8e5839fa629363f93f6550d035c/src/nvim/search.c#L631-L647
- https://github.com/neovim/neovim/blob/c194acbfc479d8e5839fa629363f93f6550d035c/src/nvim/search.c#L939-L954
---------
Co-authored-by: Justin M. Keyes <justinkz@gmail.com>
Diffstat (limited to 'src/nvim/ex_getln.c')
-rw-r--r-- | src/nvim/ex_getln.c | 9 |
1 files changed, 2 insertions, 7 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index 969023b70d..f77822cec6 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -236,7 +236,7 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s bool delim_optional = false; int delim; char *end; - char *dummy; + const char *dummy; pos_T save_cursor; bool use_last_pat; bool retval = false; @@ -261,7 +261,6 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s return false; } - emsg_off++; exarg_T ea = { .line1 = 1, .line2 = 1, @@ -369,7 +368,6 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s curwin->w_cursor = save_cursor; retval = true; theend: - emsg_off--; return retval; } @@ -2428,13 +2426,10 @@ static bool cmdpreview_may_show(CommandLineState *s) // Copy the command line so we can modify it. int cmdpreview_type = 0; char *cmdline = xstrdup(ccline.cmdbuff); - char *errormsg = NULL; - emsg_off++; // Block errors when parsing the command line, and don't update v:errmsg + const char *errormsg = NULL; if (!parse_cmdline(cmdline, &ea, &cmdinfo, &errormsg)) { - emsg_off--; goto end; } - emsg_off--; // Check if command is previewable, if not, don't attempt to show preview if (!(ea.argt & EX_PREVIEW)) { |