Skip to content
This repository was archived by the owner on Nov 9, 2017. It is now read-only.

Commit 7fbd422

Browse files
jiangxinjrn
authored andcommitted
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: Tvangeste <[email protected]> Helped-by: Johannes Sixt <[email protected]> Signed-off-by: Jiang Xin <[email protected]> Signed-off-by: Jonathan Nieder <[email protected]>
1 parent daf19a8 commit 7fbd422

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

path.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,6 +441,16 @@ int adjust_shared_perm(const char *path)
441441
return 0;
442442
}
443443

444+
static int have_same_root(const char *path1, const char *path2)
445+
{
446+
int is_abs1, is_abs2;
447+
448+
is_abs1 = is_absolute_path(path1);
449+
is_abs2 = is_absolute_path(path2);
450+
return (is_abs1 && is_abs2 && tolower(path1[0]) == tolower(path2[0])) ||
451+
(!is_abs1 && !is_abs2);
452+
}
453+
444454
/*
445455
* Give path as relative to prefix.
446456
*
@@ -461,6 +471,16 @@ const char *relative_path(const char *in, const char *prefix,
461471
else if (!prefix_len)
462472
return in;
463473

474+
if (have_same_root(in, prefix)) {
475+
/* bypass dos_drive, for "c:" is identical to "C:" */
476+
if (has_dos_drive_prefix(in)) {
477+
i = 2;
478+
j = 2;
479+
}
480+
} else {
481+
return in;
482+
}
483+
464484
while (i < prefix_len && j < in_len && prefix[i] == in[j]) {
465485
if (is_dir_sep(prefix[i])) {
466486
while (is_dir_sep(prefix[i]))

t/t0060-path-utils.sh

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,10 @@ relative_path foo/a/b/ foo/a/b ./
210210
relative_path foo/a foo/a/b ../
211211
relative_path foo/x/y foo/a/b ../../x/y
212212
relative_path foo/a/c foo/a/b ../c
213+
relative_path foo/a/b /foo/x/y foo/a/b
214+
relative_path /foo/a/b foo/x/y /foo/a/b
215+
relative_path d:/a/b D:/a/c ../b MINGW
216+
relative_path C:/a/b D:/a/c C:/a/b MINGW
213217
relative_path foo/a/b "<empty>" foo/a/b
214218
relative_path foo/a/b "<null>" foo/a/b
215219
relative_path "<empty>" /foo/a/b ./

0 commit comments

Comments
 (0)