[PATCH 2/2] [cmd] Fix basic cmd.exe /c "echo hello" type syntax
Ann and Jason Edmeades
jason at edmeades.me.uk
Mon Oct 1 18:44:03 CDT 2012
Add checks for existance of command to run in order to keep the
new quote handling capabilities of cmd.exe /C or /K. If the command
cannot be found, drop back to /S processing mode as per cmd.exe help.
cmd.exe defaults /S off unless certain conditions are met - these
conditions are spelt out in cmd.exe /? help on windows. Specifically,
a command such as cmd.exe /c "echo hello" matches all the conditions
other than the string in quotes being an executable, which we do not
currently check.
[Fixes bug 21927 and possibly 25738]
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20121002/9ae54bc7/attachment.html>
-------------- next part --------------
From 87929ebfb7f68f179a103e917bc86278a991cbce Mon Sep 17 00:00:00 2001
From: Jason Edmeades <jason at edmeades.me.uk>
Date: Tue, 2 Oct 2012 00:35:47 +0100
Subject: [PATCH 2/2] [cmd] Fix basic cmd.exe /c "echo hello" type syntax
Add checks for existance of command to run in order to keep the
new quote handling capabilities of cmd.exe /C or /K. If the command
cannot be found, drop back to /S processing mode as per cmd.exe help.
cmd.exe defaults /S off unless certain conditions are met - these
conditions are spelt out in cmd.exe /? help on windows. Specifically,
a command such as cmd.exe /c "echo hello" matches all the conditions
other than the string in quotes being an executable, which we do not
currently check.
[Fixes bug 21927 and possibly 25738]
---
programs/cmd/tests/test_builtins.cmd | 1 +
programs/cmd/tests/test_builtins.cmd.exp | 7 +--
programs/cmd/wcmdmain.c | 71 +++++++++++++++++++++++++++++-
3 files changed, 74 insertions(+), 5 deletions(-)
diff --git a/programs/cmd/tests/test_builtins.cmd b/programs/cmd/tests/test_builtins.cmd
index 1c0f875..3e064b9 100644
--- a/programs/cmd/tests/test_builtins.cmd
+++ b/programs/cmd/tests/test_builtins.cmd
@@ -1829,6 +1829,7 @@ rem Basic test of command line. Note a section prefix per command
rem to resync, as wine does not output anything in these cases yet.
echo --- Test 1
cmd.exe /c echo Line1
+cmd.exe /c echo "Line2"
echo --- Test 2
cmd.exe /c echo Test quotes "&" work
echo --- Test 3
diff --git a/programs/cmd/tests/test_builtins.cmd.exp b/programs/cmd/tests/test_builtins.cmd.exp
index e817706..6483f1e 100644
--- a/programs/cmd/tests/test_builtins.cmd.exp
+++ b/programs/cmd/tests/test_builtins.cmd.exp
@@ -910,6 +910,7 @@ value1
------------ cmd.exe command lines ------------
--- Test 1
Line1
+ at todo_wine@"Line2"
--- Test 2
@todo_wine at Test quotes "&" work
--- Test 3
@@ -929,11 +930,11 @@ Line1
--- Test 10
--- Test 11
--- Test 12
- at todo_wine@passed1
+passed1
--- Test 13
- at todo_wine@passed2 at space@
+passed2 at space@
--- Test 14
- at todo_wine@foobar
+foobar
--- Test 15
No prompts or I would not get here1
No prompts or I would not get here2
diff --git a/programs/cmd/wcmdmain.c b/programs/cmd/wcmdmain.c
index 0e7a197..675256b 100644
--- a/programs/cmd/wcmdmain.c
+++ b/programs/cmd/wcmdmain.c
@@ -2419,10 +2419,12 @@ int wmain (int argc, WCHAR *argvW[])
}
}
+ /* If there is not exactly 2 quote characters, then /S (old behaviour) is enabled */
if (qcount!=2)
opt_s = TRUE;
- /* check argvW[0] for a space and invalid characters */
+ /* check argvW[0] for a space and invalid characters. There must not be any invalid
+ * characters, but there must be one or more whitespace */
if (!opt_s) {
opt_s = TRUE;
p=*argvW;
@@ -2432,7 +2434,7 @@ int wmain (int argc, WCHAR *argvW[])
opt_s = TRUE;
break;
}
- if (*p==' ')
+ if (*p==' ' || *p=='\t')
opt_s = FALSE;
p++;
}
@@ -2507,6 +2509,71 @@ int wmain (int argc, WCHAR *argvW[])
WINE_TRACE("/c command line: '%s'\n", wine_dbgstr_w(cmd));
+ /* Finally, we only stay in new mode IF the first parameter is quoted and
+ is a valid executable, ie must exist, otherwise drop back to old mode */
+ if (!opt_s) {
+ WCHAR *thisArg = WCMD_parameter(cmd, 0, NULL, NULL, FALSE);
+ static const WCHAR extEXEW[] = {'.','e','x','e','\0'};
+ static const WCHAR extCOMW[] = {'.','c','o','m','\0'};
+ BOOL found = FALSE;
+
+ /* If the supplied parameter has any directory information, look there */
+ WINE_TRACE("First parameter is '%s'\n", wine_dbgstr_w(thisArg));
+ if (strchrW(thisArg, '\\') != NULL) {
+
+ GetFullPathNameW(thisArg, sizeof(string)/sizeof(WCHAR), string, NULL);
+ WINE_TRACE("Full path name '%s'\n", wine_dbgstr_w(string));
+ p = string + strlenW(string);
+
+ /* Does file exist with this name? */
+ if (GetFileAttributesW(string) != INVALID_FILE_ATTRIBUTES) {
+ WINE_TRACE("Found file as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ } else strcpyW(p, extEXEW);
+
+ /* Does file exist with .exe appended */
+ if (!found && GetFileAttributesW(string) != INVALID_FILE_ATTRIBUTES) {
+ WINE_TRACE("Found file as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ } else strcpyW(p, extCOMW);
+
+ /* Does file exist with .com appended */
+ if (!found && GetFileAttributesW(string) != INVALID_FILE_ATTRIBUTES) {
+ WINE_TRACE("Found file as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ }
+
+ /* Otherwise we now need to look in the path to see if we can find it */
+ } else {
+ p = thisArg + strlenW(thisArg);
+
+ /* Does file exist with this name? */
+ if (SearchPathW(NULL, thisArg, NULL, sizeof(string)/sizeof(WCHAR), string, NULL) != 0) {
+ WINE_TRACE("Found on path as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ }
+
+ /* Does file exist plus an extension of .exe? */
+ if (SearchPathW(NULL, thisArg, extEXEW, sizeof(string)/sizeof(WCHAR), string, NULL) != 0) {
+ WINE_TRACE("Found on path as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ }
+
+ /* Does file exist plus an extension of .com? */
+ if (SearchPathW(NULL, thisArg, extCOMW, sizeof(string)/sizeof(WCHAR), string, NULL) != 0) {
+ WINE_TRACE("Found on path as '%s'\n", wine_dbgstr_w(string));
+ found = TRUE;
+ }
+ }
+
+ /* If not found, drop back to old behaviour */
+ if (!found) {
+ WINE_TRACE("Binary not found, dropping back to old behaviour\n");
+ opt_s = TRUE;
+ }
+
+ }
+
/* strip first and last quote characters if opt_s; check for invalid
* executable is done later */
if (opt_s && *cmd=='\"')
--
1.7.9.5
More information about the wine-patches
mailing list