diff options
-rw-r--r-- | src/misc2.c | 25 | ||||
-rw-r--r-- | src/version.c | 2 |
2 files changed, 26 insertions, 1 deletions
diff --git a/src/misc2.c b/src/misc2.c index 04f038b9a..6895955c3 100644 --- a/src/misc2.c +++ b/src/misc2.c @@ -1262,7 +1262,9 @@ vim_strsave_escaped_ext(string, esc_chars, cc, bsl) * Escape "string" for use as a shell argument with system(). * This uses single quotes, except when we know we need to use double qoutes * (MS-DOS and MS-Windows without 'shellslash' set). - * Also replace "%", "#" and things like "<cfile>" when "do_special" is TRUE. + * Escape a newline, depending on the 'shell' option. + * When "do_special" is TRUE also replace "!", "%", "#" and things starting + * with "<" like "<cfile>". * Returns the result in allocated memory, NULL if we have run out. */ char_u * @@ -1275,6 +1277,13 @@ vim_strsave_shellescape(string, do_special) char_u *d; char_u *escaped_string; int l; + int csh_like; + + /* Only csh and similar shells expand '!' within single quotes. For sh and + * the like we must not put a backslash before it, it will be taken + * literally. If do_special is set the '!' will be escaped twice. + * Csh also needs to have "\n" escaped twice when do_special is set. */ + csh_like = (strstr((char *)gettail(p_sh), "csh") != NULL); /* First count the number of extra bytes required. */ length = (unsigned)STRLEN(string) + 3; /* two quotes and a trailing NUL */ @@ -1290,6 +1299,12 @@ vim_strsave_shellescape(string, do_special) # endif if (*p == '\'') length += 3; /* ' => '\'' */ + if (*p == '\n' || (*p == '!' && (csh_like || do_special))) + { + ++length; /* insert backslash */ + if (csh_like && do_special) + ++length; /* insert backslash */ + } if (do_special && find_cmdline_var(p, &l) >= 0) { ++length; /* insert backslash */ @@ -1335,6 +1350,14 @@ vim_strsave_shellescape(string, do_special) ++p; continue; } + if (*p == '\n' || (*p == '!' && (csh_like || do_special))) + { + *d++ = '\\'; + if (csh_like && do_special) + *d++ = '\\'; + *d++ = *p++; + continue; + } if (do_special && find_cmdline_var(p, &l) >= 0) { *d++ = '\\'; /* insert backslash */ diff --git a/src/version.c b/src/version.c index 18881a73c..95d6d54f0 100644 --- a/src/version.c +++ b/src/version.c @@ -677,6 +677,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 5, +/**/ 4, /**/ 3, |