Skip to content

Commit a34f5b0

Browse files
committed
win32: refactor git_win32_path_remove_namespace
Update `git_win32_path_remove_namespace` to disambiguate the prefix being removed versus the prefix being added. Now we remove the "namespace", and (may) add a "prefix" in its place. Eg, we remove the `\\?\` namespace. We remove the `\\?\UNC\` namespace, and replace it with the `\\` prefix. This aids readability somewhat. Additionally, use pointer arithmetic instead of offsets, which seems to also help readability.
1 parent 16fd9ba commit a34f5b0

File tree

1 file changed

+36
-25
lines changed

1 file changed

+36
-25
lines changed

src/win32/path_w32.c

Lines changed: 36 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -418,46 +418,57 @@ size_t git_win32_path_trim_end(wchar_t *str, size_t len)
418418
*/
419419
size_t git_win32_path_remove_namespace(wchar_t *str, size_t len)
420420
{
421-
static const wchar_t dosdevices_prefix[] = L"\\\?\?\\";
422-
static const wchar_t nt_prefix[] = L"\\\\?\\";
423-
static const wchar_t unc_prefix[] = L"UNC\\";
424-
static const wchar_t unc_canonicalized_prefix[] = L"\\\\";
421+
static const wchar_t dosdevices_namespace[] = L"\\\?\?\\";
422+
static const wchar_t nt_namespace[] = L"\\\\?\\";
423+
static const wchar_t unc_namespace_remainder[] = L"UNC\\";
424+
static const wchar_t unc_prefix[] = L"\\\\";
425425

426-
size_t to_advance = 0;
426+
const wchar_t *prefix = NULL, *remainder = NULL;
427+
size_t prefix_len = 0, remainder_len = 0;
427428

428429
/* "\??\" -- DOS Devices prefix */
429-
if (len >= CONST_STRLEN(dosdevices_prefix) &&
430-
!wcsncmp(str, dosdevices_prefix, CONST_STRLEN(dosdevices_prefix))) {
431-
to_advance += CONST_STRLEN(dosdevices_prefix);
432-
len -= CONST_STRLEN(dosdevices_prefix);
430+
if (len >= CONST_STRLEN(dosdevices_namespace) &&
431+
!wcsncmp(str, dosdevices_namespace, CONST_STRLEN(dosdevices_namespace))) {
432+
remainder = str + CONST_STRLEN(dosdevices_namespace);
433+
remainder_len = len - CONST_STRLEN(dosdevices_namespace);
433434
}
434435
/* "\\?\" -- NT namespace prefix */
435-
else if (len >= CONST_STRLEN(nt_prefix) &&
436-
!wcsncmp(str, nt_prefix, CONST_STRLEN(nt_prefix))) {
437-
to_advance += CONST_STRLEN(nt_prefix);
438-
len -= CONST_STRLEN(nt_prefix);
436+
else if (len >= CONST_STRLEN(nt_namespace) &&
437+
!wcsncmp(str, nt_namespace, CONST_STRLEN(nt_namespace))) {
438+
remainder = str + CONST_STRLEN(nt_namespace);
439+
remainder_len = len - CONST_STRLEN(nt_namespace);
439440
}
440441

441442
/* "\??\UNC\", "\\?\UNC\" -- UNC prefix */
442-
if (to_advance && len >= CONST_STRLEN(unc_prefix) &&
443-
!wcsncmp(str + to_advance, unc_prefix, CONST_STRLEN(unc_prefix))) {
443+
if (remainder_len >= CONST_STRLEN(unc_namespace_remainder) &&
444+
!wcsncmp(remainder, unc_namespace_remainder, CONST_STRLEN(unc_namespace_remainder))) {
444445

445446
/*
446447
* The proper Win32 path for a UNC share has "\\" at beginning of it
447-
* and looks like "\\server\share\<folderStructure>".
448-
* So, remove the UNC prefix, but leave room for a "\\"
448+
* and looks like "\\server\share\<folderStructure>". So remove the
449+
* UNC namespace and add a prefix of "\\" in its place.
449450
*/
450-
to_advance += (CONST_STRLEN(unc_prefix) - CONST_STRLEN(unc_canonicalized_prefix));
451-
len -= (CONST_STRLEN(unc_prefix) - CONST_STRLEN(unc_canonicalized_prefix));
451+
remainder += CONST_STRLEN(unc_namespace_remainder);
452+
remainder_len -= CONST_STRLEN(unc_namespace_remainder);
452453

453-
/**
454-
* Place a "\\" in the string so the result is "\\server\\share\<folderStructure>"
455-
*/
456-
memmove(str + to_advance, unc_canonicalized_prefix, CONST_STRLEN(unc_canonicalized_prefix) * sizeof(wchar_t));
454+
prefix = unc_prefix;
455+
prefix_len = CONST_STRLEN(unc_prefix);
457456
}
458457

459-
if (to_advance) {
460-
memmove(str, str + to_advance, len * sizeof(wchar_t));
458+
if (remainder) {
459+
/*
460+
* Sanity check that the new string isn't longer than the old one.
461+
* (This could only happen due to programmer error introducing a
462+
* prefix longer than the namespace it replaces.)
463+
*/
464+
assert(len >= remainder_len + prefix_len);
465+
466+
if (prefix)
467+
memmove(str, prefix, prefix_len * sizeof(wchar_t));
468+
469+
memmove(str + prefix_len, remainder, remainder_len * sizeof(wchar_t));
470+
471+
len = remainder_len + prefix_len;
461472
str[len] = L'\0';
462473
}
463474

0 commit comments

Comments
 (0)