diff --git a/src/url.lua b/src/url.lua index 110ea94..29b6734 100644 --- a/src/url.lua +++ b/src/url.lua @@ -88,20 +88,18 @@ local function absolute_path(base_path, relative_path) if string.sub(relative_path, 1, 1) == "/" then return relative_path end local path = string.gsub(base_path, "[^/]*$", "") path = path .. relative_path - path = string.gsub(path, "([^/]*%./)", function (s) - if s ~= "./" then return s else return "" end - end) - path = string.gsub(path, "/%.$", "/") - local reduced - while reduced ~= path do - reduced = path - path = string.gsub(reduced, "([^/]*/%.%./)", function (s) - if s ~= "../../" then return "" else return s end - end) - end - path = string.gsub(reduced, "([^/]*/%.%.)$", function (s) - if s ~= "../.." then return "" else return s end - end) + repeat + local was = path + path = path:gsub('/%./', '/') + until path == was + repeat + local was = path + path = path:gsub('[^/]+/%.%./([^/]+)', '%1') + until path == was + path = path:gsub('[^/]+/%.%./*$', '') + path = path:gsub('/%.%.$', '/') + path = path:gsub('/%.$', '/') + path = path:gsub('^/%.%.', '') return path end diff --git a/test/urltest.lua b/test/urltest.lua index 1090a7e..63a33ea 100644 --- a/test/urltest.lua +++ b/test/urltest.lua @@ -61,7 +61,7 @@ end local check_absolute_url = function(base, relative, absolute) local res = socket.url.absolute(base, relative) if res ~= absolute then - io.write("absolute: In test for '", relative, "' expected '", + io.write("absolute: In test for base='", base, "', rel='", relative, "' expected '", absolute, "' but got '", res, "'\n") os.exit() end @@ -637,6 +637,17 @@ check_absolute_url("http://a/b/c/d;p?q#f", "g;x", "http://a/b/c/g;x") check_absolute_url("http://a/b/c/d;p?q#f", "g;x?y#s", "http://a/b/c/g;x?y#s") check_absolute_url("http://a/b/c/d;p?q#f", ".", "http://a/b/c/") check_absolute_url("http://a/b/c/d;p?q#f", "./", "http://a/b/c/") +check_absolute_url("http://a/b/c/d;p?q#f", "./g", "http://a/b/c/g") +check_absolute_url("http://a/b/c/d;p?q#f", "./g/", "http://a/b/c/g/") +check_absolute_url("http://a/b/c/d;p?q#f", "././g", "http://a/b/c/g") +check_absolute_url("http://a/b/c/d;p?q#f", "././g/", "http://a/b/c/g/") +check_absolute_url("http://a/b/c/d;p?q#f", "g/.", "http://a/b/c/g/") +check_absolute_url("http://a/b/c/d;p?q#f", "g/./", "http://a/b/c/g/") +check_absolute_url("http://a/b/c/d;p?q#f", "g/./.", "http://a/b/c/g/") +check_absolute_url("http://a/b/c/d;p?q#f", "g/././", "http://a/b/c/g/") +check_absolute_url("http://a/b/c/d;p?q#f", "./.", "http://a/b/c/") +check_absolute_url("http://a/b/c/d;p?q#f", "././.", "http://a/b/c/") +check_absolute_url("http://a/b/c/d;p?q#f", "././g/./.", "http://a/b/c/g/") check_absolute_url("http://a/b/c/d;p?q#f", "..", "http://a/b/") check_absolute_url("http://a/b/c/d;p?q#f", "../", "http://a/b/") check_absolute_url("http://a/b/c/d;p?q#f", "../g", "http://a/b/g") @@ -655,6 +666,17 @@ check_absolute_url("http://a/b/c/d;p?q#f", "./g/.", "http://a/b/c/g/") check_absolute_url("http://a/b/c/d;p?q#f", "g/./h", "http://a/b/c/g/h") check_absolute_url("http://a/b/c/d;p?q#f", "g/../h", "http://a/b/c/h") +check_absolute_url("http://a/b/c/d:p?q#f/", "../g/", "http://a/b/g/") +check_absolute_url("http://a/b/c/d:p?q#f/", "../g", "http://a/b/g") +check_absolute_url("http://a/b/c/d:p?q#f/", "../.g/", "http://a/b/.g/") +check_absolute_url("http://a/b/c/d:p?q#f/", "../.g", "http://a/b/.g") +check_absolute_url("http://a/b/c/d:p?q#f/", "../.g.h/", "http://a/b/.g.h/") +check_absolute_url("http://a/b/c/d:p?q#f/", "../.g.h", "http://a/b/.g.h") + +check_absolute_url("http://a/b/c/d:p?q#f/", "g.h/", "http://a/b/c/g.h/") +check_absolute_url("http://a/b/c/d:p?q#f/", "../g.h/", "http://a/b/g.h/") +check_absolute_url("http://a/", "../g.h/", "http://a/g.h/") + -- extra tests check_absolute_url("//a/b/c/d;p?q#f", "d/e/f", "//a/b/c/d/e/f") check_absolute_url("/a/b/c/d;p?q#f", "d/e/f", "/a/b/c/d/e/f") @@ -662,6 +684,7 @@ check_absolute_url("a/b/c/d", "d/e/f", "a/b/c/d/e/f") check_absolute_url("a/b/c/d/../", "d/e/f", "a/b/c/d/e/f") check_absolute_url("http://velox.telemar.com.br", "/dashboard/index.html", "http://velox.telemar.com.br/dashboard/index.html") +check_absolute_url("http://example.com/", "../.badhost.com/", "http://example.com/.badhost.com/") print("testing path parsing and composition") check_parse_path("/eu/tu/ele", { "eu", "tu", "ele"; is_absolute = 1 })