mirror of
https://git.proxmox.com/git/libgit2
synced 2025-06-23 01:10:12 +00:00
commit
c6e2621052
38
src/path.c
38
src/path.c
@ -515,23 +515,33 @@ bool git_path_is_empty_dir(const char *path)
|
|||||||
WIN32_FIND_DATAW findData;
|
WIN32_FIND_DATAW findData;
|
||||||
HANDLE hFind = FindFirstFileW(filter_w, &findData);
|
HANDLE hFind = FindFirstFileW(filter_w, &findData);
|
||||||
|
|
||||||
|
/* FindFirstFile will fail if there are no children to the given
|
||||||
|
* path, which can happen if the given path is a file (and obviously
|
||||||
|
* has no children) or if the given path is an empty mount point.
|
||||||
|
* (Most directories have at least directory entries '.' and '..',
|
||||||
|
* but ridiculously another volume mounted in another drive letter's
|
||||||
|
* path space do not, and thus have nothing to enumerate.) If
|
||||||
|
* FindFirstFile fails, check if this is a directory-like thing
|
||||||
|
* (a mount point).
|
||||||
|
*/
|
||||||
|
if (hFind == INVALID_HANDLE_VALUE)
|
||||||
|
return git_path_isdir(path);
|
||||||
|
|
||||||
/* If the find handle was created successfully, then it's a directory */
|
/* If the find handle was created successfully, then it's a directory */
|
||||||
if (hFind != INVALID_HANDLE_VALUE) {
|
empty = true;
|
||||||
empty = true;
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
/* Allow the enumeration to return . and .. and still be considered
|
/* Allow the enumeration to return . and .. and still be considered
|
||||||
* empty. In the special case of drive roots (i.e. C:\) where . and
|
* empty. In the special case of drive roots (i.e. C:\) where . and
|
||||||
* .. do not occur, we can still consider the path to be an empty
|
* .. do not occur, we can still consider the path to be an empty
|
||||||
* directory if there's nothing there. */
|
* directory if there's nothing there. */
|
||||||
if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
|
if (!git_path_is_dot_or_dotdotW(findData.cFileName)) {
|
||||||
empty = false;
|
empty = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while (FindNextFileW(hFind, &findData));
|
} while (FindNextFileW(hFind, &findData));
|
||||||
|
|
||||||
FindClose(hFind);
|
FindClose(hFind);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return empty;
|
return empty;
|
||||||
|
@ -131,6 +131,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(
|
||||||
@ -177,7 +182,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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user