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; }