Commit b2fa95a0 by Edward Thomson

p_lstat win32: don't canonicalize volume mounts

A reparse point that is an IO_REPARSE_TAG_MOUNT_POINT could be
a junction or an actual filesystem mount point.  (Who knew?)
If it's the latter, its reparse point will report the actual
volume information \??\Volume{GUID}\ and we should not attempt
to dereference that further, instead readlink should report
EINVAL since it's not a symlink / junction and its original
path was canonical.

Yes, really.
parent 01a1be3f
...@@ -110,6 +110,11 @@ GIT_INLINE(time_t) filetime_to_time_t(const FILETIME *ft) ...@@ -110,6 +110,11 @@ GIT_INLINE(time_t) filetime_to_time_t(const FILETIME *ft)
return (time_t)winTime; return (time_t)winTime;
} }
static bool path_is_volume(wchar_t *target, size_t target_len)
{
return (target_len && wcsncmp(target, L"\\??\\Volume{", 11) == 0);
}
/* On success, returns the length, in characters, of the path stored in dest. /* On success, returns the length, in characters, of the path stored in dest.
* On failure, returns a negative value. */ * On failure, returns a negative value. */
static int readlink_w( static int readlink_w(
...@@ -156,7 +161,13 @@ static int readlink_w( ...@@ -156,7 +161,13 @@ static int readlink_w(
goto on_error; goto on_error;
} }
if (target_len) { if (path_is_volume(target, target_len)) {
/* This path is a reparse point that represents another volume mounted
* at this location, it is not a symbolic link our input was canonical.
*/
errno = EINVAL;
error = -1;
} else if (target_len) {
/* The path may need to have a prefix removed. */ /* The path may need to have a prefix removed. */
target_len = git_win32__canonicalize_path(target, target_len); target_len = git_win32__canonicalize_path(target, target_len);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment