Open vapaamies opened 3 years ago
Using SysInternals Process Monitor I was able to determine that the hook handling shell was run with this command:
C:\Windows\system32\cmd.exe /d /s /c ""C:\Windows\System32\sh.exe" -lc 'C:\\\\Users\\\\rmy\\\\Documents\\\\gitrepo\\\\.git\\\\hooks\\\\post-checkout 28cb6036508444c3747a0fed2ce94438a0970992 28cb6036508444c3747a0fed2ce94438a0970992 1'"
That's a heck of a lot of backslashes and quite a lot of quotes.
The arguments the busybox-w32 shell saw were:
argv[0] c:/windows/system32/sh
argv[1] -lc
argv[2] 'C:\\\\\\\\Users\\\\\\\\rmy\\\\\\\\Documents\\\\\\\\gitrepo\\\\\\\\.git\\\\\\\\hooks\\\\\\\\post-checkout
argv[3] 28cb6036508444c3747a0fed2ce94438a0970992
argv[4] 28cb6036508444c3747a0fed2ce94438a0970992
argv[5] 1'
This has even more backslashes!
The argument to the -c
option was intended to be everything in single quotes, but they clearly haven't had the desired effect. The shell is trying to run the command 'C:\\\\\\\\Users\\\\\\\\rmy\\\\\\\\Documents\\\\\\\\gitrepo\\\\\\\\.git\\\\\\\\hooks\\\\\\\\post-checkout
which, as the error states, is an unterminated quoted string. The closing single quote doesn't appear until argv[5]
which again is improperly terminated.
There should only be three arguments: the path to the shell, the options -lc
and the string the shell is supposed to run (without any quotes).
It's possible GitKraken could avoid this problem by using double quotes instead of single quotes, but Windows command lines are a bit of a mystery.
There isn't much busybox-w32 can do about it. It gets its arguments from the mingw-w64 start-up code which calls the Microsoft __getmainargs
or __wgetmainargs
functions to split the command line string into separate arguments.
Apparently the MSYS2 shell from MinGit has its own, different arrangements.
Sent feedback to GitKraken Team.
@rmyorston
Is it possible to bypass Windows command line parsing entirely?
Maybe just ignoring argv, using LPSTR GetCommandLineA();
to get raw command line and using custom code to parse it like a Linux shell would avoid all issues with '
Is it possible to bypass Windows command line parsing entirely?
Sure, it's possible. I don't think it's a good idea, though.
Because of reasons busybox-w32 already has two modes of command line handling. These are both necessary so parsing the command line like a Linux shell would require a third mode.
It's a can of worms I'd prefer not to open.
Incidentally, to expand a bit on what I mentioned above, the MSYS2 shell does appear to perform its own command line processing:
C:\Users\rmy>c:\msys64\usr\bin\sh -c 'echo hello'
hello
This is definitely not how a standard WIN32 application would process that command line:
C:\Users\rmy>cmd /c 'echo hello'
''echo' is not recognized as an internal or external command,
operable program or batch file.
C:\Users\rmy>c:\users\rmy\sh -c 'echo hello'
hello': line 0: syntax error: unterminated quoted string
cmd.exe
and the busybox-w32 shell are both standard WIN32 applications and don't like the single quotes. Everyone likes double quotes, though:
C:\Users\rmy>c:\msys64\usr\bin\sh -c "echo hello"
hello
C:\Users\rmy>cmd /c "echo hello"
hello
C:\Users\rmy>c:\users\rmy\sh -c "echo hello"
hello
It appears that GitKraken is relying on the non-standard (from a Windows perspective) behaviour of the MSYS2 shell.
Is it possible to bypass Windows command line parsing entirely?
Sure, it's possible. I don't think it's a good idea, though.
Because of reasons busybox-w32 already has two modes of command line handling. These are both necessary so parsing the command line like a Linux shell would require a third mode.
I'm not sure if it is possible, but isn't possible to reuse the command line parsing inside ash shell of busybox and with its result override argv and argc?
PS: The zip.exe also override it, since when using * in zip command line it ignore the shell expansion and use its own.
The zip.exe also override it
Related: issue #235
When set as Git hooks interpreter in GitKraken, BusyBox shell ends with error:
This is
post-checkout
hook. Thepost-checkout
is empty script:I have to use the shell from MinGit without BusyBox, it works as expected. But being executed inside the hook running by that shell, BusyBox works well too.
After a short research, I suspect bad
$PATH
variable handling. It contains the(
character because ofC:/Program Files (x86)/NVIDIA Corporation/PhysX/Common
added automatically by NVidia driver.