patch 8.2.3071: shell options are not set properly for PowerShell
Problem: Shell options are not set properly for PowerShell.
Solution: Use better option defaults. (Mike Willams, closes #8459)
diff --git a/src/misc2.c b/src/misc2.c
index 0553c2c..6bbfbd7 100644
--- a/src/misc2.c
+++ b/src/misc2.c
@@ -1396,7 +1396,9 @@
/*
* Escape "string" for use as a shell argument with system().
* This uses single quotes, except when we know we need to use double quotes
- * (MS-DOS and MS-Windows without 'shellslash' set).
+ * (MS-DOS and MS-Windows not using PowerShell and without 'shellslash' set).
+ * PowerShell also uses a novel escaping for enclosed single quotes - double
+ * them up.
* Escape a newline, depending on the 'shell' option.
* When "do_special" is TRUE also replace "!", "%", "#" and things starting
* with "<" like "<cfile>".
@@ -1412,6 +1414,10 @@
char_u *escaped_string;
int l;
int csh_like;
+# ifdef MSWIN
+ int powershell;
+ int double_quotes;
+# endif
// 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
@@ -1419,12 +1425,18 @@
// Csh also needs to have "\n" escaped twice when do_special is set.
csh_like = csh_like_shell();
+# ifdef MSWIN
+ // PowerShell only accepts single quotes so override p_ssl.
+ powershell = strstr((char *)gettail(p_sh), "powershell") != NULL;
+ double_quotes = !powershell && !p_ssl;
+# endif
+
// First count the number of extra bytes required.
length = (unsigned)STRLEN(string) + 3; // two quotes and a trailing NUL
for (p = string; *p != NUL; MB_PTR_ADV(p))
{
# ifdef MSWIN
- if (!p_ssl)
+ if (double_quotes)
{
if (*p == '"')
++length; // " -> ""
@@ -1432,7 +1444,14 @@
else
# endif
if (*p == '\'')
- length += 3; // ' => '\''
+ {
+# ifdef MSWIN
+ if (powershell)
+ length +=2; // ' => ''
+ else
+# endif
+ length += 3; // ' => '\''
+ }
if ((*p == '\n' && (csh_like || do_newline))
|| (*p == '!' && (csh_like || do_special)))
{
@@ -1455,7 +1474,7 @@
// add opening quote
# ifdef MSWIN
- if (!p_ssl)
+ if (double_quotes)
*d++ = '"';
else
# endif
@@ -1464,7 +1483,7 @@
for (p = string; *p != NUL; )
{
# ifdef MSWIN
- if (!p_ssl)
+ if (double_quotes)
{
if (*p == '"')
{
@@ -1478,10 +1497,20 @@
# endif
if (*p == '\'')
{
- *d++ = '\'';
- *d++ = '\\';
- *d++ = '\'';
- *d++ = '\'';
+# ifdef MSWIN
+ if (powershell)
+ {
+ *d++ = '\'';
+ *d++ = '\'';
+ }
+ else
+# endif
+ {
+ *d++ = '\'';
+ *d++ = '\\';
+ *d++ = '\'';
+ *d++ = '\'';
+ }
++p;
continue;
}
@@ -1507,7 +1536,7 @@
// add terminating quote and finish with a NUL
# ifdef MSWIN
- if (!p_ssl)
+ if (double_quotes)
*d++ = '"';
else
# endif