Skip to content

Commit

Permalink
normalize_path_copy(): fix pushing to //server/share/dir on Windows
Browse files Browse the repository at this point in the history
normalize_path_copy() is not prepared to keep the double-slash of a
//server/share/dir kind of path, but treats it like a regular POSIX
style path and transforms it to /server/share/dir.

The bug manifests when 'git push //server/share/dir master' is run,
because tmp_objdir_add_as_alternate() uses the path in normalized
form when it registers the quarantine object database via
link_alt_odb_entries(). Needless to say that the directory cannot be
accessed using the wrongly normalized path.

Fix it by skipping all of the root part, not just a potential drive
prefix. offset_1st_component takes care of this, see the
implementation in compat/mingw.c::mingw_offset_1st_component().

Signed-off-by: Johannes Sixt <j6t@kdbg.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
  • Loading branch information
j6t authored and gitster committed Dec 16, 2016
1 parent 0202c41 commit 7814fbe
Showing 1 changed file with 14 additions and 9 deletions.
23 changes: 14 additions & 9 deletions path.c
Original file line number Diff line number Diff line change
Expand Up @@ -961,7 +961,7 @@ const char *remove_leading_path(const char *in, const char *prefix)
*
* Performs the following normalizations on src, storing the result in dst:
* - Ensures that components are separated by '/' (Windows only)
* - Squashes sequences of '/'.
* - Squashes sequences of '/' except "//server/share" on Windows
* - Removes "." components.
* - Removes ".." components, and the components the precede them.
* Returns failure (non-zero) if a ".." component appears as first path
Expand All @@ -984,17 +984,22 @@ const char *remove_leading_path(const char *in, const char *prefix)
int normalize_path_copy_len(char *dst, const char *src, int *prefix_len)
{
char *dst0;
int i;
const char *end;

for (i = has_dos_drive_prefix(src); i > 0; i--)
*dst++ = *src++;
/*
* Copy initial part of absolute path: "/", "C:/", "//server/share/".
*/
end = src + offset_1st_component(src);
while (src < end) {
char c = *src++;
if (is_dir_sep(c))
c = '/';
*dst++ = c;
}
dst0 = dst;

if (is_dir_sep(*src)) {
*dst++ = '/';
while (is_dir_sep(*src))
src++;
}
while (is_dir_sep(*src))
src++;

for (;;) {
char c = *src;
Expand Down

0 comments on commit 7814fbe

Please sign in to comment.