Commit 7fbd4221 authored by Jiang Xin's avatar Jiang Xin Committed by Jonathan Nieder

relative_path should honor dos-drive-prefix

Tvangeste found that the "relative_path" function could not work
properly on Windows if "in" and "prefix" have DOS drive prefix
(such as "C:/windows"). ($gmane/234434)

E.g., When execute: test-path-utils relative_path "C:/a/b" "D:/x/y",
should return "C:/a/b", but returns "../../C:/a/b", which is wrong.

So make relative_path honor DOS drive prefix, and add test cases
for it in t0060.
Reported-by: default avatarTvangeste <[email protected]>
Helped-by: default avatarJohannes Sixt <[email protected]>
Signed-off-by: Jiang Xin's avatarJiang Xin <[email protected]>
Signed-off-by: default avatarJonathan Nieder <[email protected]>
parent daf19a80
......@@ -441,6 +441,16 @@ int adjust_shared_perm(const char *path)
return 0;
static int have_same_root(const char *path1, const char *path2)
int is_abs1, is_abs2;
is_abs1 = is_absolute_path(path1);
is_abs2 = is_absolute_path(path2);
return (is_abs1 && is_abs2 && tolower(path1[0]) == tolower(path2[0])) ||
(!is_abs1 && !is_abs2);
* Give path as relative to prefix.
......@@ -461,6 +471,16 @@ const char *relative_path(const char *in, const char *prefix,
else if (!prefix_len)
return in;
if (have_same_root(in, prefix)) {
/* bypass dos_drive, for "c:" is identical to "C:" */
if (has_dos_drive_prefix(in)) {
i = 2;
j = 2;
} else {
return in;
while (i < prefix_len && j < in_len && prefix[i] == in[j]) {
if (is_dir_sep(prefix[i])) {
while (is_dir_sep(prefix[i]))
......@@ -210,6 +210,10 @@ relative_path foo/a/b/ foo/a/b ./
relative_path foo/a foo/a/b ../
relative_path foo/x/y foo/a/b ../../x/y
relative_path foo/a/c foo/a/b ../c
relative_path foo/a/b /foo/x/y foo/a/b
relative_path /foo/a/b foo/x/y /foo/a/b
relative_path d:/a/b D:/a/c ../b MINGW
relative_path C:/a/b D:/a/c C:/a/b MINGW
relative_path foo/a/b "<empty>" foo/a/b
relative_path foo/a/b "<null>" foo/a/b
relative_path "<empty>" /foo/a/b ./
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment