Skip to content

Commit f7c6795

Browse files
committed
path: only treat paths starting with '\' as absolute on Win32
Windows-based systems treat paths starting with '\' as absolute, either referring to the current drive's root (e.g. "\foo" might refer to "C:\foo") or to a network path (e.g. "\\host\foo"). On the other hand, (most?) systems that are not based on Win32 accept backslashes as valid characters that may be part of the filename, and thus we cannot treat them to identify absolute paths. Change the logic to only paths starting with '\' as absolute on the Win32 platform. Add tests to avoid regressions and document behaviour.
1 parent 01dda5f commit f7c6795

File tree

2 files changed

+14
-1
lines changed

2 files changed

+14
-1
lines changed

src/path.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,12 @@ int git_path_root(const char *path)
276276
while (path[offset] && path[offset] != '/' && path[offset] != '\\')
277277
offset++;
278278
}
279+
280+
if (path[offset] == '\\')
281+
return offset;
279282
#endif
280283

281-
if (path[offset] == '/' || path[offset] == '\\')
284+
if (path[offset] == '/')
282285
return offset;
283286

284287
return -1; /* Not a real error - signals that path is not rooted */

tests/path/core.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,16 @@ void test_path_core__join_unrooted(void)
343343
test_join_unrooted("c:/foo", 2, "c:/foo", "c:/asdf");
344344
test_join_unrooted("c:/foo/bar", 2, "c:/foo/bar", "c:/asdf");
345345

346+
#ifdef GIT_WIN32
347+
/* Paths starting with '\\' are absolute */
348+
test_join_unrooted("\\bar", 0, "\\bar", "c:/foo/");
349+
test_join_unrooted("\\\\network\\bar", 9, "\\\\network\\bar", "c:/foo/");
350+
#else
351+
/* Paths starting with '\\' are not absolute on non-Windows systems */
352+
test_join_unrooted("/foo/\\bar", 4, "\\bar", "/foo");
353+
test_join_unrooted("c:/foo/\\bar", 7, "\\bar", "c:/foo/");
354+
#endif
355+
346356
/* Base is returned when it's provided and is the prefix */
347357
test_join_unrooted("c:/foo/bar/foobar", 6, "c:/foo/bar/foobar", "c:/foo");
348358
test_join_unrooted("c:/foo/bar/foobar", 10, "c:/foo/bar/foobar", "c:/foo/bar");

0 commit comments

Comments
 (0)