From 5ca6c9e04629fee4e9f1f9786e9d36a2f892160c Mon Sep 17 00:00:00 2001 From: Luki446 Date: Sat, 11 Nov 2023 22:32:08 +0100 Subject: fix(terminal): make backslashes in 'shell' work on Windows If backslashes are used in 'shell' option, escape them to make Terminal mode work. --- src/nvim/ex_docmd.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 0b466bbe4e..245121f4af 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7424,7 +7424,9 @@ static void ex_terminal(exarg_T *eap) char shell_argv[512] = { 0 }; while (*p != NULL) { - snprintf(tempstring, sizeof(tempstring), ",\"%s\"", *p); + char *escaped = vim_strsave_escaped(*p, "\"\\"); + snprintf(tempstring, sizeof(tempstring), ",\"%s\"", escaped); + xfree(escaped); xstrlcat(shell_argv, tempstring, sizeof(shell_argv)); p++; } -- cgit From 543e0256c19f397921a332e06b423215fd9aecb5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 30 Nov 2023 15:51:05 +0800 Subject: build: don't define FUNC_ATTR_* as empty in headers (#26317) FUNC_ATTR_* should only be used in .c files with generated headers. Defining FUNC_ATTR_* as empty in headers causes misuses of them to be silently ignored. Instead don't define them by default, and only define them as empty after a .c file has included its generated header. --- src/nvim/ex_docmd.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 245121f4af..bf5a3944e6 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -39,7 +39,6 @@ #include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" -#include "nvim/func_attr.h" #include "nvim/garray.h" #include "nvim/getchar.h" #include "nvim/gettext.h" -- cgit From 130cb4815a5c6625a938b1e93a7d60d7a38ad8dd Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Fri, 1 Dec 2023 13:56:04 +0800 Subject: fix(api): use a conditional stack for nvim_cmd (#26341) --- src/nvim/ex_docmd.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index bf5a3944e6..90b816bb6f 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -1711,6 +1711,9 @@ int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview) goto end; } + cstack_T cstack = { .cs_idx = -1 }; + eap->cstack = &cstack; + // Execute the command execute_cmd0(&retv, eap, &errormsg, preview); -- cgit From 6346987601a28b00564295ee8be0a8b00d9ff911 Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Thu, 7 Dec 2023 23:46:57 +0600 Subject: refactor(options): reduce `findoption()` usage Problem: Many places in the code use `findoption()` to access an option using its name, even if the option index is available. This is very slow because it requires looping through the options array over and over. Solution: Use option index instead of name wherever possible. Also introduce an `OptIndex` enum which contains the index for every option as enum constants, this eliminates the need to pass static option names as strings. --- src/nvim/ex_docmd.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 90b816bb6f..ff80ee9e54 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -2653,7 +2653,7 @@ static void apply_cmdmod(cmdmod_T *cmod) // Set 'eventignore' to "all". // First save the existing option value for restoring it later. cmod->cmod_save_ei = xstrdup(p_ei); - set_string_option_direct("ei", -1, "all", OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, "all", OPT_FREE, SID_NONE); } } @@ -2673,7 +2673,7 @@ void undo_cmdmod(cmdmod_T *cmod) if (cmod->cmod_save_ei != NULL) { // Restore 'eventignore' to the value before ":noautocmd". - set_string_option_direct("ei", -1, cmod->cmod_save_ei, OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, cmod->cmod_save_ei, OPT_FREE, SID_NONE); free_string_option(cmod->cmod_save_ei); cmod->cmod_save_ei = NULL; } @@ -7306,7 +7306,7 @@ static void ex_setfiletype(exarg_T *eap) arg += 9; } - set_option_value_give_err("filetype", CSTR_AS_OPTVAL(arg), OPT_LOCAL); + set_option_value_give_err(kOptFiletype, CSTR_AS_OPTVAL(arg), OPT_LOCAL); if (arg != eap->arg) { did_filetype = false; } -- cgit From 69bc519b53ebf78fd95c8256468e7d538ebcb948 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Tue, 12 Dec 2023 15:40:21 +0100 Subject: refactor: move non-symbols to defs.h headers --- src/nvim/ex_docmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index ff80ee9e54..d8e2c54efa 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -29,7 +29,7 @@ #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" -#include "nvim/event/loop.h" +#include "nvim/event/defs.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_cmds_defs.h" -- cgit From 7f6b775b45de5011ff1c44e63e57551566d80704 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 16 Dec 2023 22:14:28 +0100 Subject: refactor: use `bool` to represent boolean values --- src/nvim/ex_docmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index d8e2c54efa..c268f47323 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -6212,7 +6212,7 @@ static void ex_redir(exarg_T *eap) semsg(_(e_invarg2), eap->arg); } } else if (*arg == '=' && arg[1] == '>') { - int append; + bool append; // redirect to a variable close_redir(); -- cgit From af93a74a0f4afa9a3a4f55ffdf28141eaf776d22 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Mon, 18 Dec 2023 10:55:23 +0100 Subject: refactor: run IWYU on entire repo Reference: https://github.com/neovim/neovim/issues/6371. --- src/nvim/ex_docmd.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index c268f47323..70c8dc9019 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include "auto/config.h" #include "nvim/arglist.h" @@ -29,7 +29,8 @@ #include "nvim/eval.h" #include "nvim/eval/typval.h" #include "nvim/eval/userfunc.h" -#include "nvim/event/defs.h" +#include "nvim/event/loop.h" +#include "nvim/event/multiqueue.h" #include "nvim/ex_cmds.h" #include "nvim/ex_cmds2.h" #include "nvim/ex_cmds_defs.h" -- cgit From 2877672d70e76f71ae1190090b8aea7044d458be Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Mon, 25 Dec 2023 10:21:13 +0800 Subject: feat(health): make :checkhealth support more split modifiers (#26731) --- src/nvim/ex_docmd.c | 44 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 70c8dc9019..964ddca887 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7386,6 +7386,44 @@ void set_pressedreturn(bool val) ex_pressedreturn = val; } +/// ":checkhealth [plugins]" +static void ex_checkhealth(exarg_T *eap) +{ + Error err = ERROR_INIT; + MAXSIZE_TEMP_ARRAY(args, 2); + + char mods[1024]; + size_t mods_len = 0; + mods[0] = NUL; + + if (cmdmod.cmod_tab > 0 || cmdmod.cmod_split != 0) { + bool multi_mods = false; + mods_len = add_win_cmd_modifiers(mods, &cmdmod, &multi_mods); + assert(mods_len < sizeof(mods)); + } + ADD_C(args, STRING_OBJ(((String){ .data = mods, .size = mods_len }))); + ADD_C(args, CSTR_AS_OBJ(eap->arg)); + + NLUA_EXEC_STATIC("return vim.health._check(...)", args, &err); + if (!ERROR_SET(&err)) { + return; + } + + const char *vimruntime_env = os_getenv("VIMRUNTIME"); + if (vimruntime_env == NULL) { + emsg(_("E5009: $VIMRUNTIME is empty or unset")); + } else { + bool rtp_ok = NULL != strstr(p_rtp, vimruntime_env); + if (rtp_ok) { + semsg(_("E5009: Invalid $VIMRUNTIME: %s"), vimruntime_env); + } else { + emsg(_("E5009: Invalid 'runtimepath'")); + } + } + semsg_multiline(err.msg); + api_clear_error(&err); +} + static void ex_terminal(exarg_T *eap) { char ex_cmd[1024]; @@ -7393,10 +7431,8 @@ static void ex_terminal(exarg_T *eap) if (cmdmod.cmod_tab > 0 || cmdmod.cmod_split != 0) { bool multi_mods = false; - - // ex_cmd must be a null terminated string before passing to add_win_cmd_modifiers - ex_cmd[0] = '\0'; - + // ex_cmd must be a null-terminated string before passing to add_win_cmd_modifiers + ex_cmd[0] = NUL; len = add_win_cmd_modifiers(ex_cmd, &cmdmod, &multi_mods); assert(len < sizeof(ex_cmd)); int result = snprintf(ex_cmd + len, sizeof(ex_cmd) - len, " new"); -- cgit From c89292fcb7f2ebf06efb7c1d00c28f34c6f68fec Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 28 Dec 2023 13:42:24 +0100 Subject: refactor: follow style guide --- src/nvim/ex_docmd.c | 64 ++++++++++++++++++++++++++--------------------------- 1 file changed, 31 insertions(+), 33 deletions(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 964ddca887..0b6efdaab6 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -190,8 +190,8 @@ static void restore_dbg_stuff(struct dbg_stuff *dsp) trylevel = dsp->trylevel; force_abort = dsp->force_abort; caught_stack = dsp->caught_stack; - (void)v_exception(dsp->vv_exception); - (void)v_throwpoint(dsp->vv_throwpoint); + v_exception(dsp->vv_exception); + v_throwpoint(dsp->vv_throwpoint); did_emsg = dsp->did_emsg; got_int = dsp->got_int; did_throw = dsp->did_throw; @@ -710,7 +710,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) } // Convert an interrupt to an exception if appropriate. - (void)do_intthrow(&cstack); + do_intthrow(&cstack); // Continue executing command lines when: // - no CTRL-C typed, no aborting error, no exception thrown or try @@ -1703,8 +1703,8 @@ int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview) && eap->addr_type == ADDR_LINES) { // Put the first line at the start of a closed fold, put the last line // at the end of a closed fold. - (void)hasFolding(eap->line1, &eap->line1, NULL); - (void)hasFolding(eap->line2, NULL, &eap->line2); + hasFolding(eap->line1, &eap->line1, NULL); + hasFolding(eap->line2, NULL, &eap->line2); } // Use first argument as count when possible @@ -1958,7 +1958,7 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter } if (!ea.skip && got_int) { ea.skip = true; - (void)do_intthrow(cstack); + do_intthrow(cstack); } // 4. Parse a range specifier of the form: addr [,addr] [;addr] .. @@ -2170,8 +2170,8 @@ static char *do_one_cmd(char **cmdlinep, int flags, cstack_T *cstack, LineGetter && ea.addr_type == ADDR_LINES) { // Put the first line at the start of a closed fold, put the last line // at the end of a closed fold. - (void)hasFolding(ea.line1, &ea.line1, NULL); - (void)hasFolding(ea.line2, NULL, &ea.line2); + hasFolding(ea.line1, &ea.line1, NULL); + hasFolding(ea.line2, NULL, &ea.line2); } // For the ":make" and ":grep" commands we insert the 'makeprg'/'grepprg' @@ -3259,7 +3259,7 @@ static const char *addr_error(cmd_addr_T addr_type) /// @param errormsg Error message, if any /// /// @return MAXLNUM when no Ex address was found. -static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int skip, bool silent, +static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, bool skip, bool silent, int to_other_file, int address_count, const char **errormsg) FUNC_ATTR_NONNULL_ALL { @@ -3379,7 +3379,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int fmark_T *fm = mark_get(curbuf, curwin, NULL, flag, *cmd); cmd++; if (fm != NULL && fm->fnum != curbuf->handle) { - (void)mark_move_to(fm, 0); + mark_move_to(fm, 0); // Jumped to another file. lnum = curwin->w_cursor.lnum; } else { @@ -3553,7 +3553,7 @@ static linenr_T get_address(exarg_T *eap, char **ptr, cmd_addr_T addr_type, int // closed fold after the first address. if (addr_type == ADDR_LINES && (i == '-' || i == '+') && address_count >= 2) { - (void)hasFolding(lnum, NULL, &lnum); + hasFolding(lnum, NULL, &lnum); } if (i == '-') { lnum -= n; @@ -3780,12 +3780,12 @@ int expand_filename(exarg_T *eap, char **cmdlinep, const char **errormsgp) // Decide to expand wildcards *before* replacing '%', '#', etc. If // the file name contains a wildcard it should not cause expanding. // (it will be expanded anyway if there is a wildcard before replacing). - int has_wildcards = path_has_wildcard(p); + bool has_wildcards = path_has_wildcard(p); while (*p != NUL) { // Skip over `=expr`, wildcards in it are not expanded. if (p[0] == '`' && p[1] == '=') { p += 2; - (void)skip_expr(&p, NULL); + skip_expr(&p, NULL); if (*p == '`') { p++; } @@ -3860,9 +3860,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, const char **errormsgp) || eap->cmdidx == CMD_bang || eap->cmdidx == CMD_terminal) && strpbrk(repl, "!") != NULL) { - char *l; - - l = vim_strsave_escaped(repl, "!"); + char *l = vim_strsave_escaped(repl, "!"); xfree(repl); repl = l; } @@ -3890,7 +3888,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, const char **errormsgp) p = NULL; } if (p != NULL) { - (void)repl_cmdline(eap, eap->arg, strlen(eap->arg), p, cmdlinep); + repl_cmdline(eap, eap->arg, strlen(eap->arg), p, cmdlinep); } } @@ -3918,7 +3916,7 @@ int expand_filename(exarg_T *eap, char **cmdlinep, const char **errormsgp) if (p == NULL) { return FAIL; } - (void)repl_cmdline(eap, eap->arg, strlen(eap->arg), p, cmdlinep); + repl_cmdline(eap, eap->arg, strlen(eap->arg), p, cmdlinep); xfree(p); } } @@ -4004,7 +4002,7 @@ void separate_nextcmd(exarg_T *eap) } else if (p[0] == '`' && p[1] == '=' && (eap->argt & EX_XFILE)) { // Skip over `=expr` when wildcards are expanded. p += 2; - (void)skip_expr(&p, NULL); + skip_expr(&p, NULL); if (*p == NUL) { // stop at NUL after CTRL-V break; } @@ -4063,7 +4061,7 @@ static char *getargcmd(char **argp) /// Find end of "+command" argument. Skip over "\ " and "\\". /// /// @param rembs true to halve the number of backslashes -char *skip_cmd_arg(char *p, int rembs) +char *skip_cmd_arg(char *p, bool rembs) { while (*p && !ascii_isspace(*p)) { if (*p == '\\' && p[1] != NUL) { @@ -4376,7 +4374,7 @@ static void ex_doautocmd(exarg_T *eap) int call_do_modelines = check_nomodeline(&arg); bool did_aucmd; - (void)do_doautocmd(arg, false, &did_aucmd); + do_doautocmd(arg, false, &did_aucmd); // Only when there is no . if (call_do_modelines && did_aucmd) { do_modelines(0); @@ -4508,7 +4506,7 @@ char *check_nextcmd(char *p) /// @param message when false check only, no messages /// /// @return FAIL and give error message if 'message' true, return OK otherwise -static int check_more(int message, bool forceit) +static int check_more(bool message, bool forceit) { int n = ARGCOUNT - curwin->w_arg_idx - 1; @@ -5371,9 +5369,9 @@ void do_exedit(exarg_T *eap, win_T *old_curwin) || eap->cmdidx == CMD_vnew) && *eap->arg == NUL) { // ":new" or ":tabnew" without argument: edit a new empty buffer setpcmark(); - (void)do_ecmd(0, NULL, NULL, eap, ECMD_ONE, - ECMD_HIDE + (eap->forceit ? ECMD_FORCEIT : 0), - old_curwin == NULL ? curwin : NULL); + do_ecmd(0, NULL, NULL, eap, ECMD_ONE, + ECMD_HIDE + (eap->forceit ? ECMD_FORCEIT : 0), + old_curwin == NULL ? curwin : NULL); } else if ((eap->cmdidx != CMD_split && eap->cmdidx != CMD_vsplit) || *eap->arg != NUL) { // Can't edit another file when "textlock" or "curbuf->b_ro_locked" is set. @@ -5555,7 +5553,7 @@ static void ex_read(exarg_T *eap) eap->line2, 0, (linenr_T)MAXLNUM, eap, 0, false); } else { if (vim_strchr(p_cpo, CPO_ALTREAD) != NULL) { - (void)setaltfname(eap->arg, eap->arg, 1); + setaltfname(eap->arg, eap->arg, 1); } i = readfile(eap->arg, NULL, eap->line2, 0, (linenr_T)MAXLNUM, eap, 0, false); @@ -5826,7 +5824,7 @@ void do_sleep(int64_t msec) // If CTRL-C was typed to interrupt the sleep, drop the CTRL-C from the // input buffer, otherwise a following call to input() fails. if (got_int) { - (void)vpeekc(); + vpeekc(); } } @@ -5911,7 +5909,7 @@ static void ex_operators(exarg_T *eap) case CMD_yank: oa.op_type = OP_YANK; - (void)op_yank(&oa, true); + op_yank(&oa, true); break; default: // CMD_rshift or CMD_lshift @@ -6053,7 +6051,7 @@ static void ex_at(exarg_T *eap) // Continue until the stuff buffer is empty and all added characters // have been consumed. while (!stuff_empty() || typebuf.tb_len > prev_len) { - (void)do_cmdline(NULL, getexline, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE); + do_cmdline(NULL, getexline, NULL, DOCMD_NOWAIT|DOCMD_VERBOSE); } exec_from_reg = save_efr; @@ -6227,7 +6225,7 @@ static void ex_redir(exarg_T *eap) } if (var_redir_start(skipwhite(arg), append) == OK) { - redir_vname = 1; + redir_vname = true; } } else { // TODO(vim): redirect to a buffer semsg(_(e_invarg2), eap->arg); @@ -6333,7 +6331,7 @@ static void close_redir(void) redir_reg = 0; if (redir_vname) { var_redir_stop(); - redir_vname = 0; + redir_vname = false; } } @@ -7174,7 +7172,7 @@ static void ex_shada(exarg_T *eap) p_shada = "'100"; } if (eap->cmdidx == CMD_rviminfo || eap->cmdidx == CMD_rshada) { - (void)shada_read_everything(eap->arg, eap->forceit, false); + shada_read_everything(eap->arg, eap->forceit, false); } else { shada_write_file(eap->arg, eap->forceit); } @@ -7245,7 +7243,7 @@ static void ex_filetype(exarg_T *eap) } } if (*arg == 'd') { - (void)do_doautocmd("filetypedetect BufRead", true, NULL); + do_doautocmd("filetypedetect BufRead", true, NULL); do_modelines(0); } } else if (strcmp(arg, "off") == 0) { -- cgit From 10f36af84d4ccb0b626cd6c79c6ba2f2735a56fd Mon Sep 17 00:00:00 2001 From: Famiu Haque Date: Wed, 10 Jan 2024 04:15:22 +0600 Subject: refactor(options): remove `OPT_FREE` (#26963) Problem: `OPT_FREE` macro doesn't seem to do anything as `P_ALLOCED` already handles allocations. Solution: Remove `OPT_FREE`. --- src/nvim/ex_docmd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 0b6efdaab6..49c5f4e610 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -2654,7 +2654,7 @@ static void apply_cmdmod(cmdmod_T *cmod) // Set 'eventignore' to "all". // First save the existing option value for restoring it later. cmod->cmod_save_ei = xstrdup(p_ei); - set_string_option_direct(kOptEventignore, "all", OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, "all", 0, SID_NONE); } } @@ -2674,7 +2674,7 @@ void undo_cmdmod(cmdmod_T *cmod) if (cmod->cmod_save_ei != NULL) { // Restore 'eventignore' to the value before ":noautocmd". - set_string_option_direct(kOptEventignore, cmod->cmod_save_ei, OPT_FREE, SID_NONE); + set_string_option_direct(kOptEventignore, cmod->cmod_save_ei, 0, SID_NONE); free_string_option(cmod->cmod_save_ei); cmod->cmod_save_ei = NULL; } -- cgit From 1813661a6197c76ea6621284570aca1d56597099 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 4 Jan 2024 15:38:16 +0100 Subject: refactor(IWYU): fix headers Remove `export` pramgas from defs headers as it causes IWYU to believe that the definitions from the defs headers comes from main header, which is not what we really want. --- src/nvim/ex_docmd.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 49c5f4e610..7c3eb47247 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -12,9 +12,12 @@ #include #include "auto/config.h" +#include "nvim/api/private/defs.h" +#include "nvim/api/private/helpers.h" #include "nvim/arglist.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" +#include "nvim/autocmd_defs.h" #include "nvim/buffer.h" #include "nvim/buffer_defs.h" #include "nvim/change.h" @@ -28,6 +31,7 @@ #include "nvim/edit.h" #include "nvim/eval.h" #include "nvim/eval/typval.h" +#include "nvim/eval/typval_defs.h" #include "nvim/eval/userfunc.h" #include "nvim/event/loop.h" #include "nvim/event/multiqueue.h" @@ -36,15 +40,18 @@ #include "nvim/ex_cmds_defs.h" #include "nvim/ex_docmd.h" #include "nvim/ex_eval.h" +#include "nvim/ex_eval_defs.h" #include "nvim/ex_getln.h" #include "nvim/file_search.h" #include "nvim/fileio.h" #include "nvim/fold.h" #include "nvim/garray.h" +#include "nvim/garray_defs.h" #include "nvim/getchar.h" -#include "nvim/gettext.h" +#include "nvim/gettext_defs.h" #include "nvim/globals.h" #include "nvim/highlight.h" +#include "nvim/highlight_defs.h" #include "nvim/highlight_group.h" #include "nvim/input.h" #include "nvim/keycodes.h" @@ -52,20 +59,25 @@ #include "nvim/macros_defs.h" #include "nvim/main.h" #include "nvim/mark.h" +#include "nvim/mark_defs.h" #include "nvim/mbyte.h" #include "nvim/memline.h" +#include "nvim/memline_defs.h" #include "nvim/memory.h" #include "nvim/message.h" #include "nvim/mouse.h" #include "nvim/move.h" #include "nvim/normal.h" +#include "nvim/normal_defs.h" #include "nvim/ops.h" #include "nvim/option.h" +#include "nvim/option_defs.h" #include "nvim/option_vars.h" #include "nvim/optionstr.h" #include "nvim/os/fs.h" #include "nvim/os/input.h" #include "nvim/os/os.h" +#include "nvim/os/os_defs.h" #include "nvim/os/shell.h" #include "nvim/path.h" #include "nvim/popupmenu.h" @@ -73,16 +85,20 @@ #include "nvim/profile.h" #include "nvim/quickfix.h" #include "nvim/regexp.h" +#include "nvim/regexp_defs.h" #include "nvim/runtime.h" +#include "nvim/runtime_defs.h" #include "nvim/search.h" #include "nvim/shada.h" #include "nvim/state.h" +#include "nvim/state_defs.h" #include "nvim/statusline.h" #include "nvim/strings.h" #include "nvim/tag.h" #include "nvim/types_defs.h" #include "nvim/ui.h" #include "nvim/undo.h" +#include "nvim/undo_defs.h" #include "nvim/usercmd.h" #include "nvim/vim_defs.h" #include "nvim/window.h" -- cgit From 7367838359bfb5fadf72ea2aeea2f84efb34590e Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 27 Jan 2024 14:03:44 +0800 Subject: fix(api): limit depth of nvim_cmd (#27225) --- src/nvim/ex_docmd.c | 47 +++++++++++++++++++++++++++++++++++++---------- 1 file changed, 37 insertions(+), 10 deletions(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 7c3eb47247..12e746d49e 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -309,6 +309,33 @@ static void msg_verbose_cmd(linenr_T lnum, char *cmd) no_wait_return--; } +static int cmdline_call_depth = 0; ///< recursiveness + +/// Start executing an Ex command line. +/// +/// @return FAIL if too recursive, OK otherwise. +static int do_cmdline_start(void) +{ + assert(cmdline_call_depth >= 0); + // It's possible to create an endless loop with ":execute", catch that + // here. The value of 200 allows nested function calls, ":source", etc. + // Allow 200 or 'maxfuncdepth', whatever is larger. + if (cmdline_call_depth >= 200 && cmdline_call_depth >= p_mfd) { + return FAIL; + } + cmdline_call_depth++; + start_batch_changes(); + return OK; +} + +/// End executing an Ex command line. +static void do_cmdline_end(void) +{ + cmdline_call_depth--; + assert(cmdline_call_depth >= 0); + end_batch_changes(); +} + /// Execute a simple command line. Used for translated commands like "*". int do_cmdline_cmd(const char *cmd) { @@ -359,7 +386,6 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) char *(*cmd_getline)(int, void *, int, bool); void *cmd_cookie; struct loop_cookie cmd_loop_cookie; - static int call_depth = 0; // recursiveness // For every pair of do_cmdline()/do_one_cmd() calls, use an extra memory // location for storing error messages to be converted to an exception. @@ -371,10 +397,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) msg_list = &private_msg_list; private_msg_list = NULL; - // It's possible to create an endless loop with ":execute", catch that - // here. The value of 200 allows nested function calls, ":source", etc. - // Allow 200 or 'maxfuncdepth', whatever is larger. - if (call_depth >= 200 && call_depth >= p_mfd) { + if (do_cmdline_start() == FAIL) { emsg(_(e_command_too_recursive)); // When converting to an exception, we do not include the command name // since this is not an error of the specific command. @@ -382,8 +405,6 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) msg_list = saved_msg_list; return FAIL; } - call_depth++; - start_batch_changes(); ga_init(&lines_ga, (int)sizeof(wcmd_T), 10); @@ -884,8 +905,7 @@ int do_cmdline(char *cmdline, LineGetter fgetline, void *cookie, int flags) did_endif = false; // in case do_cmdline used recursively - call_depth--; - end_batch_changes(); + do_cmdline_end(); return retval; } @@ -1669,9 +1689,13 @@ static int execute_cmd0(int *retv, exarg_T *eap, const char **errormsg, bool pre /// @param preview Execute command preview callback instead of actual command int execute_cmd(exarg_T *eap, CmdParseInfo *cmdinfo, bool preview) { - const char *errormsg = NULL; int retv = 0; + if (do_cmdline_start() == FAIL) { + emsg(_(e_command_too_recursive)); + return retv; + } + const char *errormsg = NULL; #undef ERROR #define ERROR(msg) \ do { \ @@ -1738,9 +1762,12 @@ end: if (errormsg != NULL && *errormsg != NUL) { emsg(errormsg); } + // Undo command modifiers undo_cmdmod(&cmdmod); cmdmod = save_cmdmod; + + do_cmdline_end(); return retv; #undef ERROR } -- cgit From 0353dd3029f9ce31c3894530385443a90f6677ee Mon Sep 17 00:00:00 2001 From: bfredl Date: Sun, 11 Feb 2024 15:46:14 +0100 Subject: refactor(lua): use Arena when converting from lua stack to API args and for return value of nlua_exec/nlua_call_ref, as this uses the same family of functions. NB: the handling of luaref:s is a bit of a mess. add api_luarefs_free_XX functions as a stop-gap as refactoring luarefs is a can of worms for another PR:s. as a minor feature/bug-fix, nvim_buf_call and nvim_win_call now preserves arbitrary return values. --- src/nvim/ex_docmd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/nvim/ex_docmd.c') diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c index 12e746d49e..2913f6d4e9 100644 --- a/src/nvim/ex_docmd.c +++ b/src/nvim/ex_docmd.c @@ -7445,7 +7445,7 @@ static void ex_checkhealth(exarg_T *eap) ADD_C(args, STRING_OBJ(((String){ .data = mods, .size = mods_len }))); ADD_C(args, CSTR_AS_OBJ(eap->arg)); - NLUA_EXEC_STATIC("return vim.health._check(...)", args, &err); + NLUA_EXEC_STATIC("vim.health._check(...)", args, kRetNilBool, NULL, &err); if (!ERROR_SET(&err)) { return; } -- cgit