Skip to content

Commit 622f956

Browse files
committed
fixup! mingw: implement a platform-specific strbuf_realpath()
It is possible (and supported) that `strbuf_realpath()` can work in-place, i.e. the second parameter passed to the function can refer to the `buf` field of the first parameter. Our code was ill-prepared for that, though: we first store a pointer to the last component (that does not necessarily need to exist) before calling the `GetFinalPathNameByHandleW()` function. Said function is totally allowed to produce a longer path than the original one (e.g. by prefixing it with `\\?\`, a relatively unintuitive Windows-only concept). Which would overwrite the last component part. Address that by making a full string copy of the last component. Signed-off-by: Johannes Schindelin <[email protected]>
1 parent fd21527 commit 622f956

File tree

1 file changed

+11
-6
lines changed

1 file changed

+11
-6
lines changed

compat/mingw.c

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,7 @@ char *mingw_strbuf_realpath(struct strbuf *resolved, const char *path)
13861386
DWORD ret;
13871387
int len;
13881388
const char *last_component = NULL;
1389+
char *append = NULL;
13891390

13901391
if (xutftowcs_path(wpath, path) < 0)
13911392
return NULL;
@@ -1408,7 +1409,7 @@ char *mingw_strbuf_realpath(struct strbuf *resolved, const char *path)
14081409
break; /* found start of last component */
14091410

14101411
if (p != wpath && (last_component = find_last_dir_sep(path))) {
1411-
last_component++; /* skip directory separator */
1412+
append = xstrdup(last_component + 1); /* skip directory separator */
14121413
*p = L'\0';
14131414
h = CreateFileW(wpath, 0, FILE_SHARE_READ |
14141415
FILE_SHARE_WRITE | FILE_SHARE_DELETE,
@@ -1417,25 +1418,29 @@ char *mingw_strbuf_realpath(struct strbuf *resolved, const char *path)
14171418
}
14181419
}
14191420

1420-
if (h == INVALID_HANDLE_VALUE)
1421+
if (h == INVALID_HANDLE_VALUE) {
1422+
realpath_failed:
1423+
FREE_AND_NULL(append);
14211424
return NULL;
1425+
}
14221426

14231427
ret = GetFinalPathNameByHandleW(h, wpath, ARRAY_SIZE(wpath), 0);
14241428
CloseHandle(h);
14251429
if (!ret || ret >= ARRAY_SIZE(wpath))
1426-
return NULL;
1430+
goto realpath_failed;
14271431

14281432
len = wcslen(wpath) * 3;
14291433
strbuf_grow(resolved, len);
14301434
len = xwcstoutf(resolved->buf, normalize_ntpath(wpath), len);
14311435
if (len < 0)
1432-
return NULL;
1436+
goto realpath_failed;
14331437
resolved->len = len;
14341438

1435-
if (last_component) {
1439+
if (append) {
14361440
/* Use forward-slash, like `normalize_ntpath()` */
14371441
strbuf_addch(resolved, '/');
1438-
strbuf_addstr(resolved, last_component);
1442+
strbuf_addstr(resolved, append);
1443+
FREE_AND_NULL(append);
14391444
}
14401445

14411446
return resolved->buf;

0 commit comments

Comments
 (0)