Skip to content

Commit b072d68

Browse files
committed
git-wrapper: make command-line argument skipping more robust
When we rewrite the command-line to call the *real* Git, we want to skip the first command-line parameter. The previous code worked in most circumstances, but was a bit fragile because it assumed that no fancy quoting would take place. In the next commit, we will want to have the option to skip more than just one command-line parameter, so we have to be much more careful with the command-line handling. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 8355305 commit b072d68

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

compat/win32/git-wrapper.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,8 @@ static void setup_environment(LPWSTR exepath)
116116
* untouched.
117117
*/
118118
static LPWSTR fixup_commandline(LPWSTR exepath, LPWSTR *exep, int *wait,
119-
LPWSTR prefix_args, int prefix_args_len, int is_git_command)
119+
LPWSTR prefix_args, int prefix_args_len, int is_git_command,
120+
int skip_arguments)
120121
{
121122
int wargc = 0;
122123
LPWSTR cmd = NULL, cmdline = NULL;
@@ -137,10 +138,24 @@ static LPWSTR fixup_commandline(LPWSTR exepath, LPWSTR *exep, int *wait,
137138
else
138139
wcscpy(cmd, L"git.exe");
139140

140-
/* append all after first space after the initial parameter */
141-
p = wcschr(&cmdline[wcslen(wargv[0])], L' ');
142-
if (p && *p)
141+
/* skip wargv[0], append the remaining arguments */
142+
++skip_arguments;
143+
if (skip_arguments < wargc) {
144+
int i;
145+
for (i = 0, p = cmdline; p && *p && i < skip_arguments; i++) {
146+
if (i)
147+
while (isspace(*p))
148+
p++;
149+
if (*p == L'"')
150+
p++;
151+
p += wcslen(wargv[i]);
152+
if (*p == L'"')
153+
p++;
154+
while (*p && !isspace(*p))
155+
p++;
156+
}
143157
wcscat(cmd, p);
158+
}
144159
LocalFree(wargv);
145160

146161
return cmd;
@@ -248,7 +263,7 @@ static int configure_via_resource(LPWSTR basename, LPWSTR exepath, LPWSTR exep,
248263
int main(void)
249264
{
250265
int r = 1, wait = 1, prefix_args_len = -1, needs_env_setup = 1,
251-
is_git_command = 1, start_in_home = 0;
266+
is_git_command = 1, start_in_home = 0, skip_arguments = 0;
252267
WCHAR exepath[MAX_PATH], exe[MAX_PATH];
253268
LPWSTR cmd = NULL, dir = NULL, exep = exe, prefix_args = NULL, basename;
254269
UINT codepage = 0;
@@ -326,7 +341,7 @@ int main(void)
326341
if (needs_env_setup)
327342
setup_environment(exepath);
328343
cmd = fixup_commandline(exepath, &exep, &wait,
329-
prefix_args, prefix_args_len, is_git_command);
344+
prefix_args, prefix_args_len, is_git_command, skip_arguments);
330345

331346
if (start_in_home) {
332347
int len = GetEnvironmentVariable(L"HOME", NULL, 0);

0 commit comments

Comments
 (0)