https://bugs.winehq.org/show_bug.cgi?id=42508
Bug ID: 42508 Summary: start.exe does not detect its title argument when it should (breaking .e.g URL opening in League of Legends) Product: Wine Version: unspecified Hardware: x86 OS: Linux Status: UNCONFIRMED Severity: normal Priority: P2 Component: programs Assignee: wine-bugs@winehq.org Reporter: hydratech@gmail.com Distribution: ---
Created attachment 57397 --> https://bugs.winehq.org/attachment.cgi?id=57397 Trace showing League of Legends Client attempting to open a URL.
When start.exe is invoked, its first argument in quotes that is not an argument of the application to be executed should be interpreted as the console title. Wine's start.exe fails to do so.
-- How to reproduce -- Running the following line in Wine's cmd should open a URL in your browser: Z:>start "" https://winehq.org/
the actual result is an application not found error. On Windows the same line opens the website as expected.
-- Why this is a bug -- I know this was marked as fixed in bug 10913 but the reasoning was incorrect.
The argument for stating the bug was fixed was, that when "escaping your quotes" in cmd to the title was parsed. This is however not consistent with with Windows behaviour.
As explained at the end of that bug report, if you escape your quotes in Wine's cmd start.exe parses the argument as the console title, i.e.: Z:>start "hello" cmd
I will now clarify why this is incorrect by showing Windows' behaviour.
The following command lines are not equivalent on Windows:
C:>start hello.exe
vs.
C:>start "hello.exe"
The latter will open a new cmd window titled hello.exe whereas the former attempts to execute an application named hello.exe. In other words cmd's start built-in parses its own command-line checking wether quotes where used. In fact escaping the quotes using back-slashes is invalid as it tries start a process named \hello.exe. I have tested this on both Windows 7 and Windows XP.
In other words, this is invalid: C:>start "hello.exe"
To illustrate how unintuitive this Windows behaviour is: C:>start "C:\Program Files\Application\hello.exe"
Few would guess this actually opens a console titled as such, instead of running an application. That's why I can understand the maintainers would think the bug was fixed.
Wine will however correctly emulate unescaped quote-senstive behaviour with the echo built-in: Z:>echo hoi hoi
Z:>echo "hoi" "hoi"
We can see echo being "aware" of the quotes and correctly displaying them; behaviour identical to Windows' echo built-in.
Looking at the wine source, start.exe relies on its "argv" parameter instead of using GetCommandLine() and thereby accessing the unmodified command-line. As a consequence the difference between a quoted argument and a non-quoted argument is lost as CreateProcess strips the quotes off the parameters when passing them to execve().
To quote the source of Wine's cmd.exe (wcmdmain.c): /* Can't use argc/argv as it will have stripped quotes from parameters * meaning cmd.exe /C echo "quoted string" is impossible */
It should now be evident that start.exe should either become a wrapper around cmd.exe's built-in start function, invoking cmd and let cmd itself implement start.exe's actual behaviour, or implement GetCommandLine() based argument parsing similar to cmd.exe's within start.exe, leading to duplicated command-line parsing code. Both are not ideal solutions.
-- Why does this bug matter? --
There are actually Windows applications relying on this behaviour to open URLs in the user's browser. As an example, League of Legends executes the following shell command to open a URL: cmd.exe /c start "" "<url here>"
In other words, League instructs start to launch an untitled shell window with a URL as application, effectively causing the shell to pass it to the browser. However, wine's start.exe interprets this as League trying to execute an empty string as executable name, with a URL as argument. I have attached the relevant output running League with WINEDEBUG=cmd,start,process,exec set.
I will speculate that more applications will run into this exact same issue. League's client is based on CEF and it might very well be CEF which implements this style of external URL opening, furthermore there is documentation recommending the use of empty quotes as console title argument when invoking start to prevent it from accidentally parsing follow up arguments in quotes as the console title, think "C:\Program Files\etc...", establishing this as a pattern that might well have been adopted by other applications. See: https://ss64.com/nt/start.html
I will also say that, given some instruction, I will be glad to help fixing this bug and write any necessary code.
There is actually another issue with current start.exe's console title parsing which I will submit as a separate issue. That issue is however, significantly easier to fix. Finally this also means wine's current handling of command-line arguments might need fixing as: $ wine start '""' "http://winehq.og" will break in a fixed version of 'start.exe', while it should work. For this I will file yet another issue, although the necessity of this fix is debatable.