diff --git a/src/host/path_getabsolute.c b/src/host/path_getabsolute.c index 048fd95c..94b67cd7 100644 --- a/src/host/path_getabsolute.c +++ b/src/host/path_getabsolute.c @@ -34,6 +34,9 @@ void do_getabsolute(char* result, const char* value, const char* relative_to) result[0] = '\0'; if (buffer[0] == '/') { strcat(result, "/"); + if (buffer[1] == '/') { + strcat(result, "/"); + } } prev = NULL; diff --git a/src/host/path_getrelative.c b/src/host/path_getrelative.c index a67ccdfb..e48af756 100644 --- a/src/host/path_getrelative.c +++ b/src/host/path_getrelative.c @@ -67,6 +67,14 @@ int path_getrelative(lua_State* L) return 1; } + /* Relative paths within a server can't climb outside the server root. + * If the paths don't share server name, return the absolute path. */ + if (src[0] == '/' && src[1] == '/' && last == 1) { + dst[strlen(dst) - 1] = '\0'; + lua_pushstring(L, dst); + return 1; + } + /* count remaining levels in src */ count = 0; for (i = last + 1; src[i] != '\0'; ++i) { diff --git a/src/host/path_normalize.c b/src/host/path_normalize.c index d0ab3981..309c1a18 100644 --- a/src/host/path_normalize.c +++ b/src/host/path_normalize.c @@ -70,8 +70,8 @@ static void* normalize_substring(const char* str, const char* endPtr, char* writ } } - /* add to the result, filtering out duplicate slashes */ - if (ch != '/' || last != '/') { + /* add to the result, filtering out duplicate slashes, except when they are leading slashes */ + if (str == &source[1] || (ch != '/' || last != '/')) { *(writePtr++) = ch; } diff --git a/tests/base/test_path.lua b/tests/base/test_path.lua index 77a08162..52363353 100755 --- a/tests/base/test_path.lua +++ b/tests/base/test_path.lua @@ -48,6 +48,10 @@ test.isequal("%HOME%/user", path.getabsolute("%HOME%/user")) end + function suite.getabsolute_onServerPath() + test.isequal("//Server/Volume", path.getabsolute("//Server/Volume")) + end + function suite.getabsolute_onMultipleEnvVar() test.isequal("$(HOME)/$(USER)", path.getabsolute("$(HOME)/$(USER)")) end @@ -336,6 +340,10 @@ test.isequal("obj/debug", path.getrelative("C:/Code/Premake4", "C:/Code/Premake4/obj/debug")) end + function suite.getrelative_ReturnsChildPath_OnServerPath() + test.isequal("../Volume", path.getrelative("//Server/Shared", "//Server/Volume")) + end + function suite.getrelative_ReturnsAbsPath_OnDifferentDriveLetters() test.isequal("D:/Files", path.getrelative("C:/Code/Premake4", "D:/Files")) end @@ -348,6 +356,14 @@ test.isequal("/opt/include", path.getrelative("/home/me/src/project", "/opt/include")) end + function suite.getrelative_ReturnsAbsPath_OnServerPath() + test.isequal("//Server/Volume", path.getrelative("C:/Files", "//Server/Volume")) + end + + function suite.getrelative_ReturnsAbsPath_OnDifferentServers() + test.isequal("//Server/Volume", path.getrelative("//Computer/Users", "//Server/Volume")) + end + function suite.getrelative_ignoresExtraSlashes2() test.isequal("..", path.getrelative("/a//b/c","/a/b")) end