diff --git a/spec/dir_spec.lua b/spec/dir_spec.lua index 9f05c664c..f6ef172e0 100644 --- a/spec/dir_spec.lua +++ b/spec/dir_spec.lua @@ -52,12 +52,20 @@ describe("luarocks.dir #unit", function() it("strips unneeded /../ and /./", function() assert.are.same("/some/dir/file.txt", dir.normalize("/../../../some/./foo/bar/.././../dir/bla/../file.txt")) assert.are.same("/some/dir/file.txt", dir.normalize("/../../../some/./foo/bar/.././../dir/bla/../file.txt")) + assert.are.same("/some/dir", dir.normalize("/../../../some/./foo/bar/.././../dir/./some/subdir/../..")) + assert.are.same("/some/dir", dir.normalize("/../../../some/./foo/bar/.././../dir/./.")) end) it("respects relative paths", function() + assert.are.same(".", dir.normalize(".")) assert.are.same("boo", dir.normalize("./boo")) assert.are.same("/boo", dir.normalize("/./boo")) assert.are.same("../../../../boo", dir.normalize("../../../hello/world/../../../boo")) end) + it("respects root directory", function() + assert.are.same("/", dir.normalize("/")) + assert.are.same("/", dir.normalize("/////")) + assert.are.same("/", dir.normalize("/a/b/.././../c/./../../")) + end) end) end) diff --git a/src/luarocks/core/dir.lua b/src/luarocks/core/dir.lua index 0da889979..46dbeafd0 100644 --- a/src/luarocks/core/dir.lua +++ b/src/luarocks/core/dir.lua @@ -63,6 +63,7 @@ function dir.normalize(name) if pathname:match("^.:") then drive, pathname = pathname:match("^(.:)(.*)$") end + pathname = pathname .. "/" for piece in pathname:gmatch("(.-)/") do if piece == ".." then local prev = pieces[#pieces] @@ -75,11 +76,13 @@ function dir.normalize(name) table.insert(pieces, piece) end end - local basename = pathname:match("[^/]+$") - if basename then - table.insert(pieces, basename) + if #pieces == 0 then + pathname = drive .. "." + elseif #pieces == 1 and pieces[1] == "" then + pathname = drive .. "/" + else + pathname = drive .. table.concat(pieces, "/") end - pathname = drive .. table.concat(pieces, "/") if protocol ~= "file" then pathname = protocol .."://"..pathname end return pathname end