diff --git a/options/path.c b/options/path.c index a8e39c3310..a17d8b4325 100644 --- a/options/path.c +++ b/options/path.c @@ -256,28 +256,28 @@ char *mp_splitext(const char *path, bstr *root) char *mp_path_join_bstr(void *talloc_ctx, struct bstr p1, struct bstr p2) { - bool test; if (p1.len == 0) return bstrdup0(talloc_ctx, p2); if (p2.len == 0) return bstrdup0(talloc_ctx, p1); + bool is_absolute = strchr(mp_path_separators, p2.start[0]); #if HAVE_DOS_PATHS - test = (p2.len >= 2 && p2.start[1] == ':') - || p2.start[0] == '\\' || p2.start[0] == '/'; -#else - test = p2.start[0] == '/'; + // Note: "X:filename" is a path relative to the current working directory + // of drive X, and thus is not an absolute path. It needs to be + // followed by \ or /. + if (p2.len >= 3 && p2.start[1] == ':' && + strchr(mp_path_separators, p2.start[2])) + is_absolute = true; #endif - if (test) - return bstrdup0(talloc_ctx, p2); // absolute path + if (is_absolute) + return bstrdup0(talloc_ctx, p2); - bool have_separator; - int endchar1 = p1.start[p1.len - 1]; + bool have_separator = strchr(mp_path_separators, p1.start[p1.len - 1]); #if HAVE_DOS_PATHS - have_separator = endchar1 == '/' || endchar1 == '\\' - || (p1.len == 2 && endchar1 == ':'); // "X:" only -#else - have_separator = endchar1 == '/'; + // "X:" only => path relative to "X:" current working directory. + if (p1.len == 2 && p1.start[1] == ':') + have_separator = true; #endif return talloc_asprintf(talloc_ctx, "%.*s%s%.*s", BSTR_P(p1), diff --git a/test/paths.c b/test/paths.c index 5ec2eb8859..434a7996ad 100644 --- a/test/paths.c +++ b/test/paths.c @@ -36,7 +36,7 @@ static void run(struct test_ctx *ctx) TEST_JOIN("c:\\a", "c:\\b", "c:\\b"); TEST_JOIN("c:/a", "c:/b", "c:/b"); // Note: drive-relative paths are not always supported "properly" - TEST_JOIN("c:/a", "d:b", "d:b"); + TEST_JOIN("c:/a", "d:b", "c:/a/d:b"); TEST_JOIN("c:a", "b", "c:a/b"); TEST_JOIN("c:", "b", "c:b"); #endif