aloneguid/win-shim

Shim doesn't handle spaces in arguments and executable path

Opened this issue · 0 comments

Hey @aloneguid,

Thank you for this little gem! This is the only opensource alternative to Chocolatey shim generator I've managed to find!

While playing with the tool, I've faced several issues with spaces in arguments passed to the shim executable. They can be easily reproduced in the following way:

  1. Make a shim to the mkdir command:
shmake.exe -i cmd.exe -o sample.exe -a "/c mkdir %s"
  1. Try to create a folder containing spaces in its name:
sample.exe "my folder"

Expected behavior: shim creates a single folder named my folder
Actual behavior: shim creates two separate folders named my and folder

This is caused by the following code:

wstring passed_arg;
for (int i = 1; i < argc; i++)
{
    if (i > 1) passed_arg += L" ";
    passed_arg += argv[i];
}

Unfortunately we cannot simply concatenate all arguments into a single string. Any argument that contains spaces must be enclosed in double quotes, otherwise it would be unclear where the previous argument ends, and where the next one starts.

The easiest fix is to retrieve the entire command-line string from GetCommandLine and forward it to the target process. This is exactly what scoop-better-shimexe does. GetCommandLine returns the command-line string as-is, preserving the original quotation marks around arguments. No need to manually construct the string from separate argv tokens and mess with the awkward quoting rules. There is one caveat though. The command-line string always starts with the path to the shim executable, i.e., argv[0]. This path needs to be removed from the string before doing %s token substitution.

Note that spaces may occur not only in arguments but also in executable paths like C:\Program Files. For instance:

shmake.exe -i "C:\Program Files\Git\bin\git.exe" -o sample.exe

Honestly, I didn't have any issues with such paths but some Scoop people reported that Scoop shims cannot run executables if they have a space in their path. The fix is simple: if the executable path contains spaces, enclose it in double quotes. scoop-better-shimexe already did this. It would be good to apply similar fixes here as well.