Skip to content

Commit 7b155ae

Browse files
committed
git-wrapper: Allow git-cmd.exe to add only /cmd/ to the PATH
The idea of having the Git wrapper in the /cmd/ directory is to allow adding only a *tiny* set of executables to the search path, to allow minimal interference with other software applications. It is quite likely, for example, that other software applications require their own version of zlib1.dll and would not be overly happy to find the version Git for Windows ships. The /cmd/ directory also gives us the opportunity to let the Git wrapper handle the `gitk` script. It is a Tcl/Tk script that is not recognized by Windows, therefore calling `gitk` in `cmd.exe` would not work, even if we add all of Git for Windows' bin/ directories. So let's use the /cmd/ directory instead of adding /mingw??/bin/ and /usr/bin/ to the PATH when launching Git CMD. The way we implemented Git CMD is to embed the appropriate command line as string resource into a copy of the Git wrapper. Therefore we extended that syntax to allow for configuring a minimal search path. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent 8895c14 commit 7b155ae

File tree

1 file changed

+34
-18
lines changed

1 file changed

+34
-18
lines changed

compat/win32/git-wrapper.c

Lines changed: 34 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ static void print_error(LPCWSTR prefix, DWORD error_number)
3737
LocalFree((HLOCAL)buffer);
3838
}
3939

40-
static void setup_environment(LPWSTR exepath)
40+
static void setup_environment(LPWSTR exepath, int full_path)
4141
{
4242
WCHAR msystem[64];
4343
LPWSTR path2 = NULL;
@@ -88,19 +88,23 @@ static void setup_environment(LPWSTR exepath)
8888
len = sizeof(WCHAR) * (len + 2 * MAX_PATH);
8989
path2 = (LPWSTR)malloc(len);
9090
wcscpy(path2, exepath);
91-
PathAppend(path2, msystem_bin);
92-
if (_waccess(path2, 0) != -1) {
93-
/* We are in an MSys2-based setup */
94-
wcscat(path2, L";");
95-
wcscat(path2, exepath);
96-
PathAppend(path2, L"usr\\bin;");
97-
}
91+
if (!full_path)
92+
PathAppend(path2, L"cmd;");
9893
else {
99-
/* Fall back to MSys1 paths */
100-
wcscpy(path2, exepath);
101-
PathAppend(path2, L"bin;");
102-
wcscat(path2, exepath);
103-
PathAppend(path2, L"mingw\\bin;");
94+
PathAppend(path2, msystem_bin);
95+
if (_waccess(path2, 0) != -1) {
96+
/* We are in an MSys2-based setup */
97+
wcscat(path2, L";");
98+
wcscat(path2, exepath);
99+
PathAppend(path2, L"usr\\bin;");
100+
}
101+
else {
102+
/* Fall back to MSys1 paths */
103+
wcscpy(path2, exepath);
104+
PathAppend(path2, L"bin;");
105+
wcscat(path2, exepath);
106+
PathAppend(path2, L"mingw\\bin;");
107+
}
104108
}
105109
GetEnvironmentVariable(L"PATH", path2 + wcslen(path2),
106110
(len / sizeof(WCHAR)) - wcslen(path2));
@@ -163,16 +167,18 @@ static LPWSTR fixup_commandline(LPWSTR exepath, LPWSTR *exep, int *wait,
163167

164168
static int configure_via_resource(LPWSTR basename, LPWSTR exepath, LPWSTR exep,
165169
LPWSTR *prefix_args, int *prefix_args_len,
166-
int *is_git_command, int *start_in_home, int *skip_arguments)
170+
int *is_git_command, int *start_in_home, int *full_path,
171+
int *skip_arguments)
167172
{
168-
int id, wargc;
173+
int id, minimal_search_path, wargc;
169174
LPWSTR *wargv;
170175

171176
#define BUFSIZE 65536
172177
static WCHAR buf[BUFSIZE];
173178
int len;
174179

175180
for (id = 0; ; id++) {
181+
minimal_search_path = 0;
176182
len = LoadString(NULL, id, buf, BUFSIZE);
177183

178184
if (!len) {
@@ -190,6 +196,12 @@ static int configure_via_resource(LPWSTR basename, LPWSTR exepath, LPWSTR exep,
190196
exit(1);
191197
}
192198

199+
if (!wcsncmp(L"MINIMAL_PATH=1 ", buf, 15)) {
200+
minimal_search_path = 1;
201+
memmove(buf, buf + 15,
202+
sizeof(WCHAR) * (wcslen(buf + 15) + 1));
203+
}
204+
193205
buf[len] = L'\0';
194206

195207
if (!id)
@@ -259,6 +271,8 @@ static int configure_via_resource(LPWSTR basename, LPWSTR exepath, LPWSTR exep,
259271
*start_in_home = 0;
260272
*skip_arguments = 1;
261273
}
274+
if (minimal_search_path)
275+
*full_path = 0;
262276
LocalFree(wargv);
263277

264278
return 1;
@@ -267,7 +281,8 @@ static int configure_via_resource(LPWSTR basename, LPWSTR exepath, LPWSTR exep,
267281
int main(void)
268282
{
269283
int r = 1, wait = 1, prefix_args_len = -1, needs_env_setup = 1,
270-
is_git_command = 1, start_in_home = 0, skip_arguments = 0;
284+
is_git_command = 1, start_in_home = 0, full_path = 1,
285+
skip_arguments = 0;
271286
WCHAR exepath[MAX_PATH], exe[MAX_PATH];
272287
LPWSTR cmd = NULL, dir = NULL, exep = exe, prefix_args = NULL, basename;
273288
UINT codepage = 0;
@@ -285,7 +300,8 @@ int main(void)
285300
basename = exepath + wcslen(exepath) + 1;
286301
if (configure_via_resource(basename, exepath, exep,
287302
&prefix_args, &prefix_args_len,
288-
&is_git_command, &start_in_home, &skip_arguments)) {
303+
&is_git_command, &start_in_home,
304+
&full_path, &skip_arguments)) {
289305
/* do nothing */
290306
}
291307
else if (!wcsncmp(basename, L"git-", 4)) {
@@ -343,7 +359,7 @@ int main(void)
343359
}
344360

345361
if (needs_env_setup)
346-
setup_environment(exepath);
362+
setup_environment(exepath, full_path);
347363
cmd = fixup_commandline(exepath, &exep, &wait,
348364
prefix_args, prefix_args_len, is_git_command, skip_arguments);
349365

0 commit comments

Comments
 (0)