diff options
author | Diego Nehab <diego.nehab@gmail.com> | 2018-08-22 14:18:43 -0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-22 14:18:43 -0300 |
commit | 648d81281f177f43de3d7b66e5923bdbaaeb25d9 (patch) | |
tree | cf5a837a349305ad10b54d1ce152e7cdc490edfc | |
parent | 5813cd05054599b0409480d3214f1827c2360467 (diff) | |
parent | 043e99771352aff47680b99f09b66a32f0cc3ef5 (diff) | |
download | luasocket-648d81281f177f43de3d7b66e5923bdbaaeb25d9.tar.gz luasocket-648d81281f177f43de3d7b66e5923bdbaaeb25d9.tar.bz2 luasocket-648d81281f177f43de3d7b66e5923bdbaaeb25d9.zip |
Merge pull request #256 from ewestbrook/luasocket254
url.lua:absolute_path(): fix issue #254
-rw-r--r-- | src/url.lua | 64 | ||||
-rw-r--r-- | test/urltest.lua | 44 |
2 files changed, 82 insertions, 26 deletions
diff --git a/src/url.lua b/src/url.lua index 110ea94..0a3a80a 100644 --- a/src/url.lua +++ b/src/url.lua | |||
@@ -77,6 +77,34 @@ function _M.unescape(s) | |||
77 | end | 77 | end |
78 | 78 | ||
79 | ----------------------------------------------------------------------------- | 79 | ----------------------------------------------------------------------------- |
80 | -- Removes '..' and '.' components appropriately from a path. | ||
81 | -- Input | ||
82 | -- path | ||
83 | -- Returns | ||
84 | -- dot-normalized path | ||
85 | local function remove_dot_components(path) | ||
86 | local marker = string.char(1) | ||
87 | repeat | ||
88 | local was = path | ||
89 | path = path:gsub('//', '/'..marker..'/', 1) | ||
90 | until path == was | ||
91 | repeat | ||
92 | local was = path | ||
93 | path = path:gsub('/%./', '/', 1) | ||
94 | until path == was | ||
95 | repeat | ||
96 | local was = path | ||
97 | path = path:gsub('[^/]+/%.%./([^/]+)', '%1', 1) | ||
98 | until path == was | ||
99 | path = path:gsub('[^/]+/%.%./*$', '') | ||
100 | path = path:gsub('/%.%.$', '/') | ||
101 | path = path:gsub('/%.$', '/') | ||
102 | path = path:gsub('^/%.%./', '/') | ||
103 | path = path:gsub(marker, '') | ||
104 | return path | ||
105 | end | ||
106 | |||
107 | ----------------------------------------------------------------------------- | ||
80 | -- Builds a path from a base path and a relative path | 108 | -- Builds a path from a base path and a relative path |
81 | -- Input | 109 | -- Input |
82 | -- base_path | 110 | -- base_path |
@@ -85,23 +113,12 @@ end | |||
85 | -- corresponding absolute path | 113 | -- corresponding absolute path |
86 | ----------------------------------------------------------------------------- | 114 | ----------------------------------------------------------------------------- |
87 | local function absolute_path(base_path, relative_path) | 115 | local function absolute_path(base_path, relative_path) |
88 | if string.sub(relative_path, 1, 1) == "/" then return relative_path end | 116 | if string.sub(relative_path, 1, 1) == "/" then |
89 | local path = string.gsub(base_path, "[^/]*$", "") | 117 | return remove_dot_components(relative_path) end |
90 | path = path .. relative_path | 118 | base_path = base_path:gsub("[^/]*$", "") |
91 | path = string.gsub(path, "([^/]*%./)", function (s) | 119 | if not base_path:find'/$' then base_path = base_path .. '/' end |
92 | if s ~= "./" then return s else return "" end | 120 | local path = base_path .. relative_path |
93 | end) | 121 | path = remove_dot_components(path) |
94 | path = string.gsub(path, "/%.$", "/") | ||
95 | local reduced | ||
96 | while reduced ~= path do | ||
97 | reduced = path | ||
98 | path = string.gsub(reduced, "([^/]*/%.%./)", function (s) | ||
99 | if s ~= "../../" then return "" else return s end | ||
100 | end) | ||
101 | end | ||
102 | path = string.gsub(reduced, "([^/]*/%.%.)$", function (s) | ||
103 | if s ~= "../.." then return "" else return s end | ||
104 | end) | ||
105 | return path | 122 | return path |
106 | end | 123 | end |
107 | 124 | ||
@@ -227,10 +244,14 @@ function _M.absolute(base_url, relative_url) | |||
227 | else | 244 | else |
228 | base_parsed = _M.parse(base_url) | 245 | base_parsed = _M.parse(base_url) |
229 | end | 246 | end |
247 | local result | ||
230 | local relative_parsed = _M.parse(relative_url) | 248 | local relative_parsed = _M.parse(relative_url) |
231 | if not base_parsed then return relative_url | 249 | if not base_parsed then |
232 | elseif not relative_parsed then return base_url | 250 | result = relative_url |
233 | elseif relative_parsed.scheme then return relative_url | 251 | elseif not relative_parsed then |
252 | result = base_url | ||
253 | elseif relative_parsed.scheme then | ||
254 | result = relative_url | ||
234 | else | 255 | else |
235 | relative_parsed.scheme = base_parsed.scheme | 256 | relative_parsed.scheme = base_parsed.scheme |
236 | if not relative_parsed.authority then | 257 | if not relative_parsed.authority then |
@@ -248,8 +269,9 @@ function _M.absolute(base_url, relative_url) | |||
248 | relative_parsed.path) | 269 | relative_parsed.path) |
249 | end | 270 | end |
250 | end | 271 | end |
251 | return _M.build(relative_parsed) | 272 | result = _M.build(relative_parsed) |
252 | end | 273 | end |
274 | return remove_dot_components(result) | ||
253 | end | 275 | end |
254 | 276 | ||
255 | ----------------------------------------------------------------------------- | 277 | ----------------------------------------------------------------------------- |
diff --git a/test/urltest.lua b/test/urltest.lua index 1090a7e..ae8ba75 100644 --- a/test/urltest.lua +++ b/test/urltest.lua | |||
@@ -61,7 +61,7 @@ end | |||
61 | local check_absolute_url = function(base, relative, absolute) | 61 | local check_absolute_url = function(base, relative, absolute) |
62 | local res = socket.url.absolute(base, relative) | 62 | local res = socket.url.absolute(base, relative) |
63 | if res ~= absolute then | 63 | if res ~= absolute then |
64 | io.write("absolute: In test for '", relative, "' expected '", | 64 | io.write("absolute: In test for base='", base, "', rel='", relative, "' expected '", |
65 | absolute, "' but got '", res, "'\n") | 65 | absolute, "' but got '", res, "'\n") |
66 | os.exit() | 66 | os.exit() |
67 | end | 67 | end |
@@ -627,25 +627,37 @@ check_absolute_url("http://a/b/c/d;p?q#f", "/g", "http://a/g") | |||
627 | check_absolute_url("http://a/b/c/d;p?q#f", "//g", "http://g") | 627 | check_absolute_url("http://a/b/c/d;p?q#f", "//g", "http://g") |
628 | check_absolute_url("http://a/b/c/d;p?q#f", "?y", "http://a/b/c/d;p?y") | 628 | check_absolute_url("http://a/b/c/d;p?q#f", "?y", "http://a/b/c/d;p?y") |
629 | check_absolute_url("http://a/b/c/d;p?q#f", "g?y", "http://a/b/c/g?y") | 629 | check_absolute_url("http://a/b/c/d;p?q#f", "g?y", "http://a/b/c/g?y") |
630 | check_absolute_url("http://a/b/c/d;p?q#f", "g?y/./x", "http://a/b/c/g?y/./x") | 630 | check_absolute_url("http://a/b/c/d;p?q#f", "g?y/./x", "http://a/b/c/g?y/x") |
631 | check_absolute_url("http://a/b/c/d;p?q#f", "#s", "http://a/b/c/d;p?q#s") | 631 | check_absolute_url("http://a/b/c/d;p?q#f", "#s", "http://a/b/c/d;p?q#s") |
632 | check_absolute_url("http://a/b/c/d;p?q#f", "g#s", "http://a/b/c/g#s") | 632 | check_absolute_url("http://a/b/c/d;p?q#f", "g#s", "http://a/b/c/g#s") |
633 | check_absolute_url("http://a/b/c/d;p?q#f", "g#s/./x", "http://a/b/c/g#s/./x") | 633 | check_absolute_url("http://a/b/c/d;p?q#f", "g#s/./x", "http://a/b/c/g#s/x") |
634 | check_absolute_url("http://a/b/c/d;p?q#f", "g?y#s", "http://a/b/c/g?y#s") | 634 | check_absolute_url("http://a/b/c/d;p?q#f", "g?y#s", "http://a/b/c/g?y#s") |
635 | check_absolute_url("http://a/b/c/d;p?q#f", ";x", "http://a/b/c/d;x") | 635 | check_absolute_url("http://a/b/c/d;p?q#f", ";x", "http://a/b/c/d;x") |
636 | check_absolute_url("http://a/b/c/d;p?q#f", "g;x", "http://a/b/c/g;x") | 636 | check_absolute_url("http://a/b/c/d;p?q#f", "g;x", "http://a/b/c/g;x") |
637 | check_absolute_url("http://a/b/c/d;p?q#f", "g;x?y#s", "http://a/b/c/g;x?y#s") | 637 | check_absolute_url("http://a/b/c/d;p?q#f", "g;x?y#s", "http://a/b/c/g;x?y#s") |
638 | check_absolute_url("http://a/b/c/d;p?q#f", ".", "http://a/b/c/") | 638 | check_absolute_url("http://a/b/c/d;p?q#f", ".", "http://a/b/c/") |
639 | check_absolute_url("http://a/b/c/d;p?q#f", "./", "http://a/b/c/") | 639 | check_absolute_url("http://a/b/c/d;p?q#f", "./", "http://a/b/c/") |
640 | check_absolute_url("http://a/b/c/d;p?q#f", "./g", "http://a/b/c/g") | ||
641 | check_absolute_url("http://a/b/c/d;p?q#f", "./g/", "http://a/b/c/g/") | ||
642 | check_absolute_url("http://a/b/c/d;p?q#f", "././g", "http://a/b/c/g") | ||
643 | check_absolute_url("http://a/b/c/d;p?q#f", "././g/", "http://a/b/c/g/") | ||
644 | check_absolute_url("http://a/b/c/d;p?q#f", "g/.", "http://a/b/c/g/") | ||
645 | check_absolute_url("http://a/b/c/d;p?q#f", "g/./", "http://a/b/c/g/") | ||
646 | check_absolute_url("http://a/b/c/d;p?q#f", "g/./.", "http://a/b/c/g/") | ||
647 | check_absolute_url("http://a/b/c/d;p?q#f", "g/././", "http://a/b/c/g/") | ||
648 | check_absolute_url("http://a/b/c/d;p?q#f", "./.", "http://a/b/c/") | ||
649 | check_absolute_url("http://a/b/c/d;p?q#f", "././.", "http://a/b/c/") | ||
650 | check_absolute_url("http://a/b/c/d;p?q#f", "././g/./.", "http://a/b/c/g/") | ||
640 | check_absolute_url("http://a/b/c/d;p?q#f", "..", "http://a/b/") | 651 | check_absolute_url("http://a/b/c/d;p?q#f", "..", "http://a/b/") |
641 | check_absolute_url("http://a/b/c/d;p?q#f", "../", "http://a/b/") | 652 | check_absolute_url("http://a/b/c/d;p?q#f", "../", "http://a/b/") |
642 | check_absolute_url("http://a/b/c/d;p?q#f", "../g", "http://a/b/g") | 653 | check_absolute_url("http://a/b/c/d;p?q#f", "../g", "http://a/b/g") |
643 | check_absolute_url("http://a/b/c/d;p?q#f", "../..", "http://a/") | 654 | check_absolute_url("http://a/b/c/d;p?q#f", "../..", "http://a/") |
644 | check_absolute_url("http://a/b/c/d;p?q#f", "../../", "http://a/") | 655 | check_absolute_url("http://a/b/c/d;p?q#f", "../../", "http://a/") |
645 | check_absolute_url("http://a/b/c/d;p?q#f", "../../g", "http://a/g") | 656 | check_absolute_url("http://a/b/c/d;p?q#f", "../../g", "http://a/g") |
657 | check_absolute_url("http://a/b/c/d;p?q#f", "../../../g", "http://a/g") | ||
646 | check_absolute_url("http://a/b/c/d;p?q#f", "", "http://a/b/c/d;p?q#f") | 658 | check_absolute_url("http://a/b/c/d;p?q#f", "", "http://a/b/c/d;p?q#f") |
647 | check_absolute_url("http://a/b/c/d;p?q#f", "/./g", "http://a/./g") | 659 | check_absolute_url("http://a/b/c/d;p?q#f", "/./g", "http://a/g") |
648 | check_absolute_url("http://a/b/c/d;p?q#f", "/../g", "http://a/../g") | 660 | check_absolute_url("http://a/b/c/d;p?q#f", "/../g", "http://a/g") |
649 | check_absolute_url("http://a/b/c/d;p?q#f", "g.", "http://a/b/c/g.") | 661 | check_absolute_url("http://a/b/c/d;p?q#f", "g.", "http://a/b/c/g.") |
650 | check_absolute_url("http://a/b/c/d;p?q#f", ".g", "http://a/b/c/.g") | 662 | check_absolute_url("http://a/b/c/d;p?q#f", ".g", "http://a/b/c/.g") |
651 | check_absolute_url("http://a/b/c/d;p?q#f", "g..", "http://a/b/c/g..") | 663 | check_absolute_url("http://a/b/c/d;p?q#f", "g..", "http://a/b/c/g..") |
@@ -655,6 +667,17 @@ check_absolute_url("http://a/b/c/d;p?q#f", "./g/.", "http://a/b/c/g/") | |||
655 | check_absolute_url("http://a/b/c/d;p?q#f", "g/./h", "http://a/b/c/g/h") | 667 | check_absolute_url("http://a/b/c/d;p?q#f", "g/./h", "http://a/b/c/g/h") |
656 | check_absolute_url("http://a/b/c/d;p?q#f", "g/../h", "http://a/b/c/h") | 668 | check_absolute_url("http://a/b/c/d;p?q#f", "g/../h", "http://a/b/c/h") |
657 | 669 | ||
670 | check_absolute_url("http://a/b/c/d:p?q#f/", "../g/", "http://a/b/g/") | ||
671 | check_absolute_url("http://a/b/c/d:p?q#f/", "../g", "http://a/b/g") | ||
672 | check_absolute_url("http://a/b/c/d:p?q#f/", "../.g/", "http://a/b/.g/") | ||
673 | check_absolute_url("http://a/b/c/d:p?q#f/", "../.g", "http://a/b/.g") | ||
674 | check_absolute_url("http://a/b/c/d:p?q#f/", "../.g.h/", "http://a/b/.g.h/") | ||
675 | check_absolute_url("http://a/b/c/d:p?q#f/", "../.g.h", "http://a/b/.g.h") | ||
676 | |||
677 | check_absolute_url("http://a/b/c/d:p?q#f/", "g.h/", "http://a/b/c/g.h/") | ||
678 | check_absolute_url("http://a/b/c/d:p?q#f/", "../g.h/", "http://a/b/g.h/") | ||
679 | check_absolute_url("http://a/", "../g.h/", "http://a/g.h/") | ||
680 | |||
658 | -- extra tests | 681 | -- extra tests |
659 | check_absolute_url("//a/b/c/d;p?q#f", "d/e/f", "//a/b/c/d/e/f") | 682 | check_absolute_url("//a/b/c/d;p?q#f", "d/e/f", "//a/b/c/d/e/f") |
660 | check_absolute_url("/a/b/c/d;p?q#f", "d/e/f", "/a/b/c/d/e/f") | 683 | check_absolute_url("/a/b/c/d;p?q#f", "d/e/f", "/a/b/c/d/e/f") |
@@ -662,6 +685,17 @@ check_absolute_url("a/b/c/d", "d/e/f", "a/b/c/d/e/f") | |||
662 | check_absolute_url("a/b/c/d/../", "d/e/f", "a/b/c/d/e/f") | 685 | check_absolute_url("a/b/c/d/../", "d/e/f", "a/b/c/d/e/f") |
663 | check_absolute_url("http://velox.telemar.com.br", "/dashboard/index.html", | 686 | check_absolute_url("http://velox.telemar.com.br", "/dashboard/index.html", |
664 | "http://velox.telemar.com.br/dashboard/index.html") | 687 | "http://velox.telemar.com.br/dashboard/index.html") |
688 | check_absolute_url("http://example.com/", "../.badhost.com/", "http://example.com/.badhost.com/") | ||
689 | check_absolute_url("http://example.com/", "...badhost.com/", "http://example.com/...badhost.com/") | ||
690 | check_absolute_url("http://example.com/a/b/c/d/", "../q", "http://example.com/a/b/c/q") | ||
691 | check_absolute_url("http://example.com/a/b/c/d/", "../../q", "http://example.com/a/b/q") | ||
692 | check_absolute_url("http://example.com/a/b/c/d/", "../../../q", "http://example.com/a/q") | ||
693 | check_absolute_url("http://example.com", ".badhost.com", "http://example.com/.badhost.com") | ||
694 | check_absolute_url("http://example.com/a/b/c/d/", "..//../../../q", "http://example.com/a/q") | ||
695 | check_absolute_url("http://example.com/a/b/c/d/", "..//a/../../../../q", "http://example.com/a/q") | ||
696 | check_absolute_url("http://example.com/a/b/c/d/", "..//a/..//../../../q", "http://example.com/a/b/q") | ||
697 | check_absolute_url("http://example.com/a/b/c/d/", "..//a/..///../../../../q", "http://example.com/a/b/q") | ||
698 | check_absolute_url("http://example.com/a/b/c/d/", "../x/a/../y/z/../../../../q", "http://example.com/a/b/q") | ||
665 | 699 | ||
666 | print("testing path parsing and composition") | 700 | print("testing path parsing and composition") |
667 | check_parse_path("/eu/tu/ele", { "eu", "tu", "ele"; is_absolute = 1 }) | 701 | check_parse_path("/eu/tu/ele", { "eu", "tu", "ele"; is_absolute = 1 }) |