diff options
Diffstat (limited to 'src/nvim/ex_cmds.c')
-rw-r--r-- | src/nvim/ex_cmds.c | 30 |
1 files changed, 18 insertions, 12 deletions
diff --git a/src/nvim/ex_cmds.c b/src/nvim/ex_cmds.c index e3abb14481..c406364491 100644 --- a/src/nvim/ex_cmds.c +++ b/src/nvim/ex_cmds.c @@ -3367,8 +3367,9 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n // Small incompatibility: vi sees '\n' as end of the command, but in // Vim we want to use '\n' to find/substitute a NUL. - sub = cmd; // remember the start of the substitution + char *p = cmd; // remember the start of the substitution cmd = skip_substitute(cmd, delimiter); + sub = xstrdup(p); if (!eap->skip && cmdpreview_ns <= 0) { sub_set_replacement((SubReplacementString) { @@ -3383,7 +3384,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n return 0; } pat = NULL; // search_regcomp() will use previous pattern - sub = old_sub.sub; + sub = xstrdup(old_sub.sub); // Vi compatibility quirk: repeating with ":s" keeps the cursor in the // last column after using "$". @@ -3391,6 +3392,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n } if (sub != NULL && sub_joining_lines(eap, pat, sub, cmd, cmdpreview_ns <= 0)) { + xfree(sub); return 0; } @@ -3405,11 +3407,13 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n i = getdigits_int(&cmd, true, INT_MAX); if (i <= 0 && !eap->skip && subflags.do_error) { emsg(_(e_zerocount)); + xfree(sub); return 0; } else if (i >= INT_MAX) { char buf[20]; vim_snprintf(buf, sizeof(buf), "%d", i); semsg(_(e_val_too_large), buf); + xfree(sub); return 0; } eap->line1 = eap->line2; @@ -3425,17 +3429,20 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n eap->nextcmd = check_nextcmd(cmd); if (eap->nextcmd == NULL) { semsg(_(e_trailing_arg), cmd); + xfree(sub); return 0; } } if (eap->skip) { // not executing commands, only parsing + xfree(sub); return 0; } if (!subflags.do_count && !MODIFIABLE(curbuf)) { // Substitution is not allowed in non-'modifiable' buffer emsg(_(e_modifiable)); + xfree(sub); return 0; } @@ -3444,6 +3451,7 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n if (subflags.do_error) { emsg(_(e_invcmd)); } + xfree(sub); return 0; } @@ -3458,22 +3466,20 @@ static int do_sub(exarg_T *eap, const proftime_T timeout, const int cmdpreview_n assert(sub != NULL); - char *sub_copy = NULL; - // If the substitute pattern starts with "\=" then it's an expression. // Make a copy, a recursive function may free it. // Otherwise, '~' in the substitute pattern is replaced with the old // pattern. We do it here once to avoid it to be replaced over and over // again. if (sub[0] == '\\' && sub[1] == '=') { - sub = xstrdup(sub); - sub_copy = sub; + char *p = xstrdup(sub); + xfree(sub); + sub = p; } else { - char *newsub = regtilde(sub, magic_isset(), cmdpreview_ns > 0); - if (newsub != sub) { - // newsub was allocated, free it later. - sub_copy = newsub; - sub = newsub; + char *p = regtilde(sub, magic_isset(), cmdpreview_ns > 0); + if (p != sub) { + xfree(sub); + sub = p; } } @@ -4244,7 +4250,7 @@ skip: } vim_regfree(regmatch.regprog); - xfree(sub_copy); + xfree(sub); // Restore the flag values, they can be used for ":&&". subflags.do_all = save_do_all; |