diff options
author | Edward Thomson <ethomson@edwardthomson.com> | 2018-10-17 08:48:43 -0700 |
---|---|---|
committer | Edward Thomson <ethomson@edwardthomson.com> | 2018-10-19 07:26:17 +0100 |
commit | b2e85f982709b1dee4ab7206f83d56352b165e82 (patch) | |
tree | dda0feef36772112a1a5855d8fe1b9f2f54bc5f5 /src/win32 | |
parent | 3f096ca56affd4870f6c3a5c1c045d2fb100de0d (diff) | |
download | libgit2-b2e85f982709b1dee4ab7206f83d56352b165e82.tar.gz |
win32: rename `git_win32__canonicalize_path`
The internal API `git_win32__canonicalize_path` is far, far too easily
confused with the internal API `git_win32_path_canonicalize`. The
former removes the namespace prefix from a path (eg, given
`\\?\C:\Temp\foo`, it returns `C:\Temp\foo`, and given
`\\?\UNC\server\share`, it returns `\\server\share`). As such, rename
it to `git_win32_path_remove_namespace`.
`git_win32_path_canonicalize` remains unchanged.
Diffstat (limited to 'src/win32')
-rw-r--r-- | src/win32/path_w32.c | 97 | ||||
-rw-r--r-- | src/win32/path_w32.h | 18 | ||||
-rw-r--r-- | src/win32/posix_w32.c | 6 | ||||
-rw-r--r-- | src/win32/w32_util.c | 80 | ||||
-rw-r--r-- | src/win32/w32_util.h | 18 |
5 files changed, 111 insertions, 108 deletions
diff --git a/src/win32/path_w32.c b/src/win32/path_w32.c index 5e24260f7..18dc81a33 100644 --- a/src/win32/path_w32.c +++ b/src/win32/path_w32.c @@ -220,7 +220,7 @@ int git_win32_path_from_utf8(git_win32_path out, const char *src) goto on_error; } - /* Skip the drive letter specification ("C:") */ + /* Skip the drive letter specification ("C:") */ if (git__utf8_to_16(dest + 2, MAX_PATH - 2, src) < 0) goto on_error; } @@ -315,7 +315,7 @@ static bool path_is_volume(wchar_t *target, size_t target_len) } /* 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. */ int git_win32_path_readlink_w(git_win32_path dest, const git_win32_path path) { BYTE buf[MAXIMUM_REPARSE_DATA_BUFFER_SIZE]; @@ -360,16 +360,16 @@ int git_win32_path_readlink_w(git_win32_path dest, const git_win32_path path) 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. - */ + * 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. */ - target_len = git_win32__canonicalize_path(target, target_len); + /* The path may need to have a namespace prefix removed. */ + target_len = git_win32_path_remove_namespace(target, target_len); /* Need one additional character in the target buffer - * for the terminating NULL. */ + * for the terminating NULL. */ if (GIT_WIN_PATH_UTF16 > target_len) { wcscpy(dest, target); error = (int)target_len; @@ -380,3 +380,86 @@ on_error: CloseHandle(handle); return error; } + +/** + * Removes any trailing backslashes from a path, except in the case of a drive + * letter path (C:\, D:\, etc.). This function cannot fail. + * + * @param path The path which should be trimmed. + * @return The length of the modified string (<= the input length) + */ +size_t git_win32_path_trim_end(wchar_t *str, size_t len) +{ + while (1) { + if (!len || str[len - 1] != L'\\') + break; + + /* + * Don't trim backslashes from drive letter paths, which + * are 3 characters long and of the form C:\, D:\, etc. + */ + if (len == 3 && git_win32__isalpha(str[0]) && str[1] == ':') + break; + + len--; + } + + str[len] = L'\0'; + + return len; +} + +/** + * Removes any of the following namespace prefixes from a path, + * if found: "\??\", "\\?\", "\\?\UNC\". This function cannot fail. + * + * @param path The path which should be converted. + * @return The length of the modified string (<= the input length) + */ +size_t git_win32_path_remove_namespace(wchar_t *str, size_t len) +{ + static const wchar_t dosdevices_prefix[] = L"\\\?\?\\"; + static const wchar_t nt_prefix[] = L"\\\\?\\"; + static const wchar_t unc_prefix[] = L"UNC\\"; + static const wchar_t unc_canonicalized_prefix[] = L"\\\\"; + + size_t to_advance = 0; + + /* "\??\" -- DOS Devices prefix */ + if (len >= CONST_STRLEN(dosdevices_prefix) && + !wcsncmp(str, dosdevices_prefix, CONST_STRLEN(dosdevices_prefix))) { + to_advance += CONST_STRLEN(dosdevices_prefix); + len -= CONST_STRLEN(dosdevices_prefix); + } + /* "\\?\" -- NT namespace prefix */ + else if (len >= CONST_STRLEN(nt_prefix) && + !wcsncmp(str, nt_prefix, CONST_STRLEN(nt_prefix))) { + to_advance += CONST_STRLEN(nt_prefix); + len -= CONST_STRLEN(nt_prefix); + } + + /* "\??\UNC\", "\\?\UNC\" -- UNC prefix */ + if (to_advance && len >= CONST_STRLEN(unc_prefix) && + !wcsncmp(str + to_advance, unc_prefix, CONST_STRLEN(unc_prefix))) { + + /* + * The proper Win32 path for a UNC share has "\\" at beginning of it + * and looks like "\\server\share\<folderStructure>". + * So, remove the UNC prefix, but leave room for a "\\" + */ + to_advance += (CONST_STRLEN(unc_prefix) - CONST_STRLEN(unc_canonicalized_prefix)); + len -= (CONST_STRLEN(unc_prefix) - CONST_STRLEN(unc_canonicalized_prefix)); + + /** + * Place a "\\" in the string so the result is "\\server\\share\<folderStructure>" + */ + memmove(str + to_advance, unc_canonicalized_prefix, CONST_STRLEN(unc_canonicalized_prefix) * sizeof(wchar_t)); + } + + if (to_advance) { + memmove(str, str + to_advance, len * sizeof(wchar_t)); + str[len] = L'\0'; + } + + return git_win32_path_trim_end(str, len); +} diff --git a/src/win32/path_w32.h b/src/win32/path_w32.h index 83ffd1f6f..facbced81 100644 --- a/src/win32/path_w32.h +++ b/src/win32/path_w32.h @@ -83,4 +83,22 @@ extern char *git_win32_path_8dot3_name(const char *path); extern int git_win32_path_readlink_w(git_win32_path dest, const git_win32_path path); +/** + * Removes any trailing backslashes from a path, except in the case of a drive + * letter path (C:\, D:\, etc.). This function cannot fail. + * + * @param path The path which should be trimmed. + * @return The length of the modified string (<= the input length) + */ +size_t git_win32_path_trim_end(wchar_t *str, size_t len); + +/** + * Removes any of the following namespace prefixes from a path, + * if found: "\??\", "\\?\", "\\?\UNC\". This function cannot fail. + * + * @param path The path which should be converted. + * @return The length of the modified string (<= the input length) + */ +size_t git_win32_path_remove_namespace(wchar_t *str, size_t len); + #endif diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c index 8617e45e9..8c321ef3c 100644 --- a/src/win32/posix_w32.c +++ b/src/win32/posix_w32.c @@ -354,7 +354,7 @@ static int do_lstat(const char *path, struct stat *buf, bool posixly_correct) if ((len = git_win32_path_from_utf8(path_w, path)) < 0) return -1; - git_win32__path_trim_end(path_w, len); + git_win32_path_trim_end(path_w, len); return lstat_w(path_w, buf, posixly_correct); } @@ -648,8 +648,8 @@ static int getfinalpath_w( if (!dwChars || dwChars >= GIT_WIN_PATH_UTF16) return -1; - /* The path may be delivered to us with a prefix; canonicalize */ - return (int)git_win32__canonicalize_path(dest, dwChars); + /* The path may be delivered to us with a namespace prefix; remove */ + return (int)git_win32_path_remove_namespace(dest, dwChars); } static int follow_and_lstat_link(git_win32_path path, struct stat* buf) diff --git a/src/win32/w32_util.c b/src/win32/w32_util.c index 5bacd6ebb..5996c9fb9 100644 --- a/src/win32/w32_util.c +++ b/src/win32/w32_util.c @@ -93,83 +93,3 @@ int git_win32__hidden(bool *out, const char *path) *out = (attrs & FILE_ATTRIBUTE_HIDDEN) ? true : false; return 0; } - -/** - * Removes any trailing backslashes from a path, except in the case of a drive - * letter path (C:\, D:\, etc.). This function cannot fail. - * - * @param path The path which should be trimmed. - * @return The length of the modified string (<= the input length) - */ -size_t git_win32__path_trim_end(wchar_t *str, size_t len) -{ - while (1) { - if (!len || str[len - 1] != L'\\') - break; - - /* Don't trim backslashes from drive letter paths, which - * are 3 characters long and of the form C:\, D:\, etc. */ - if (len == 3 && git_win32__isalpha(str[0]) && str[1] == ':') - break; - - len--; - } - - str[len] = L'\0'; - - return len; -} - -/** - * Removes any of the following namespace prefixes from a path, - * if found: "\??\", "\\?\", "\\?\UNC\". This function cannot fail. - * - * @param path The path which should be converted. - * @return The length of the modified string (<= the input length) - */ -size_t git_win32__canonicalize_path(wchar_t *str, size_t len) -{ - static const wchar_t dosdevices_prefix[] = L"\\\?\?\\"; - static const wchar_t nt_prefix[] = L"\\\\?\\"; - static const wchar_t unc_prefix[] = L"UNC\\"; - static const wchar_t unc_canonicalized_prefix[] = L"\\\\"; - - size_t to_advance = 0; - - /* "\??\" -- DOS Devices prefix */ - if (len >= CONST_STRLEN(dosdevices_prefix) && - !wcsncmp(str, dosdevices_prefix, CONST_STRLEN(dosdevices_prefix))) { - to_advance += CONST_STRLEN(dosdevices_prefix); - len -= CONST_STRLEN(dosdevices_prefix); - } - /* "\\?\" -- NT namespace prefix */ - else if (len >= CONST_STRLEN(nt_prefix) && - !wcsncmp(str, nt_prefix, CONST_STRLEN(nt_prefix))) { - to_advance += CONST_STRLEN(nt_prefix); - len -= CONST_STRLEN(nt_prefix); - } - - /* "\??\UNC\", "\\?\UNC\" -- UNC prefix */ - if (to_advance && len >= CONST_STRLEN(unc_prefix) && - !wcsncmp(str + to_advance, unc_prefix, CONST_STRLEN(unc_prefix))) { - /** - * The proper Win32 path for a UNC share has "\\" at beginning of it - * and looks like "\\server\share\<folderStructure>". - * So, remove th UNC prefix, but leave room for a "\\" - */ - to_advance += (CONST_STRLEN(unc_prefix) - CONST_STRLEN(unc_canonicalized_prefix)); - len -= (CONST_STRLEN(unc_prefix) - CONST_STRLEN(unc_canonicalized_prefix)); - - /** - * Place a "\\" in the string so the result is "\\server\\share\<folderStructure>" - */ - memmove(str + to_advance, unc_canonicalized_prefix, CONST_STRLEN(unc_canonicalized_prefix) * sizeof(wchar_t)); - } - - if (to_advance) { - memmove(str, str + to_advance, len * sizeof(wchar_t)); - str[len] = L'\0'; - } - - return git_win32__path_trim_end(str, len); -} diff --git a/src/win32/w32_util.h b/src/win32/w32_util.h index 6531f47a7..5216a1396 100644 --- a/src/win32/w32_util.h +++ b/src/win32/w32_util.h @@ -60,24 +60,6 @@ extern int git_win32__set_hidden(const char *path, bool hidden); extern int git_win32__hidden(bool *hidden, const char *path); /** - * Removes any trailing backslashes from a path, except in the case of a drive - * letter path (C:\, D:\, etc.). This function cannot fail. - * - * @param path The path which should be trimmed. - * @return The length of the modified string (<= the input length) - */ -size_t git_win32__path_trim_end(wchar_t *str, size_t len); - -/** - * Removes any of the following namespace prefixes from a path, - * if found: "\??\", "\\?\", "\\?\UNC\". This function cannot fail. - * - * @param path The path which should be converted. - * @return The length of the modified string (<= the input length) - */ -size_t git_win32__canonicalize_path(wchar_t *str, size_t len); - -/** * Converts a FILETIME structure to a struct timespec. * * @param FILETIME A pointer to a FILETIME |