aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHisham Muhammad <hisham@gobolinux.org>2019-12-02 17:21:20 -0300
committerHisham Muhammad <hisham@gobolinux.org>2019-12-12 15:38:28 -0300
commit129ebf34efa945b2b56a29c80b161414a98757a8 (patch)
tree3465103deec491798430fc85308ecf22244452ec
parentc9292f6b699fa1edba46a1cbeaa582e7dac2f8c6 (diff)
downloadluarocks-129ebf34efa945b2b56a29c80b161414a98757a8.tar.gz
luarocks-129ebf34efa945b2b56a29c80b161414a98757a8.tar.bz2
luarocks-129ebf34efa945b2b56a29c80b161414a98757a8.zip
win32: fix split root for quoted absolute path handling
-rw-r--r--spec/fs_spec.lua34
-rw-r--r--src/luarocks/fs/unix.lua7
-rw-r--r--src/luarocks/fs/win32.lua48
3 files changed, 70 insertions, 19 deletions
diff --git a/spec/fs_spec.lua b/spec/fs_spec.lua
index e3643f78..5d8926c4 100644
--- a/spec/fs_spec.lua
+++ b/spec/fs_spec.lua
@@ -88,6 +88,40 @@ describe("Luarocks fs test #unit", function()
88 assert.are.same(is_win and [["\\"%" \\\\" \\\\\\"]] or [['\% \\" \\\']], fs.Q([[\% \\" \\\]])) 88 assert.are.same(is_win and [["\\"%" \\\\" \\\\\\"]] or [['\% \\" \\\']], fs.Q([[\% \\" \\\]]))
89 end) 89 end)
90 end) 90 end)
91
92 describe("fs.absolute_name", function()
93 it("unchanged if already absolute", function()
94 if is_win then
95 assert.are.same("c:\\foo\\bar", fs.absolute_name("\"c:\\foo\\bar\""))
96 assert.are.same("c:\\foo\\bar", fs.absolute_name("c:\\foo\\bar"))
97 assert.are.same("d:\\foo\\bar", fs.absolute_name("d:\\foo\\bar"))
98 assert.are.same("\\foo\\bar", fs.absolute_name("\\foo\\bar"))
99 else
100 assert.are.same("/foo/bar", fs.absolute_name("/foo/bar"))
101 end
102 end)
103
104 it("converts to absolute if relative", function()
105 local cur = fs.current_dir()
106 if is_win then
107 assert.are.same(cur .. "/foo\\bar", fs.absolute_name("\"foo\\bar\""))
108 assert.are.same(cur .. "/foo\\bar", fs.absolute_name("foo\\bar"))
109 else
110 assert.are.same(cur .. "/foo/bar", fs.absolute_name("foo/bar"))
111 end
112 end)
113
114 it("converts a relative to specified base if given", function()
115 if is_win then
116 assert.are.same("c:\\bla/foo\\bar", fs.absolute_name("\"foo\\bar\"", "c:\\bla"))
117 assert.are.same("c:\\bla/foo\\bar", fs.absolute_name("foo\\bar", "c:\\bla"))
118 assert.are.same("c:\\bla/foo\\bar", fs.absolute_name("foo\\bar", "c:\\bla\\"))
119 else
120 assert.are.same("/bla/foo/bar", fs.absolute_name("foo/bar", "/bla"))
121 assert.are.same("/bla/foo/bar", fs.absolute_name("foo/bar", "/bla/"))
122 end
123 end)
124 end)
91 125
92 describe("fs.execute_string", function() 126 describe("fs.execute_string", function()
93 local tmpdir 127 local tmpdir
diff --git a/src/luarocks/fs/unix.lua b/src/luarocks/fs/unix.lua
index 164ec75d..d62a93ca 100644
--- a/src/luarocks/fs/unix.lua
+++ b/src/luarocks/fs/unix.lua
@@ -42,7 +42,12 @@ function unix.absolute_name(pathname, relative_to)
42 assert(type(pathname) == "string") 42 assert(type(pathname) == "string")
43 assert(type(relative_to) == "string" or not relative_to) 43 assert(type(relative_to) == "string" or not relative_to)
44 44
45 relative_to = relative_to or fs.current_dir() 45 local unquoted = pathname:match("^['\"](.*)['\"]$")
46 if unquoted then
47 pathname = unquoted
48 end
49
50 relative_to = (relative_to or fs.current_dir()):gsub("/*$", "")
46 if pathname:sub(1,1) == "/" then 51 if pathname:sub(1,1) == "/" then
47 return pathname 52 return pathname
48 else 53 else
diff --git a/src/luarocks/fs/win32.lua b/src/luarocks/fs/win32.lua
index b9404a73..ec75e605 100644
--- a/src/luarocks/fs/win32.lua
+++ b/src/luarocks/fs/win32.lua
@@ -32,23 +32,32 @@ function win32.quiet_stderr(cmd)
32 return cmd.." 2> NUL" 32 return cmd.." 2> NUL"
33end 33end
34 34
35-- Split path into root and the rest. 35-- Split path into drive, root and the rest.
36-- Root part consists of an optional drive letter (e.g. "C:") 36-- Example: "c:\\hello\\world" becomes "c:" "\\" "hello\\world"
37-- and an optional directory separator. 37-- if any part is missing from input, it becomes an empty string.
38local function split_root(path) 38local function split_root(pathname)
39 local drive = ""
39 local root = "" 40 local root = ""
41 local rest = ""
40 42
41 if path:match("^.:") then 43 local unquoted = pathname:match("^['\"](.*)['\"]$")
42 root = path:sub(1, 2) 44 if unquoted then
43 path = path:sub(3) 45 pathname = unquoted
44 end 46 end
45 47
46 if path:match("^[\\/]") then 48 if pathname:match("^.:") then
47 root = path:sub(1, 1) 49 drive = pathname:sub(1, 2)
48 path = path:sub(2) 50 pathname = pathname:sub(3)
49 end 51 end
50 52
51 return root, path 53 if pathname:match("^[\\/]") then
54 root = pathname:sub(1, 1)
55 rest = pathname:sub(2)
56 else
57 rest = pathname
58 end
59
60 return drive, root, rest
52end 61end
53 62
54--- Quote argument for shell processing. Fixes paths on Windows. 63--- Quote argument for shell processing. Fixes paths on Windows.
@@ -59,7 +68,8 @@ function win32.Q(arg)
59 assert(type(arg) == "string") 68 assert(type(arg) == "string")
60 -- Use Windows-specific directory separator for paths. 69 -- Use Windows-specific directory separator for paths.
61 -- Paths should be converted to absolute by now. 70 -- Paths should be converted to absolute by now.
62 if split_root(arg) ~= "" then 71 local drive, root, rest = split_root(arg)
72 if root ~= "" then
63 arg = arg:gsub("/", "\\") 73 arg = arg:gsub("/", "\\")
64 end 74 end
65 if arg == "\\" then 75 if arg == "\\" then
@@ -81,7 +91,8 @@ function win32.Qb(arg)
81 assert(type(arg) == "string") 91 assert(type(arg) == "string")
82 -- Use Windows-specific directory separator for paths. 92 -- Use Windows-specific directory separator for paths.
83 -- Paths should be converted to absolute by now. 93 -- Paths should be converted to absolute by now.
84 if split_root(arg) ~= "" then 94 local drive, root, rest = split_root(arg)
95 if root ~= "" then
85 arg = arg:gsub("/", "\\") 96 arg = arg:gsub("/", "\\")
86 end 97 end
87 if arg == "\\" then 98 if arg == "\\" then
@@ -105,11 +116,11 @@ function win32.absolute_name(pathname, relative_to)
105 assert(type(pathname) == "string") 116 assert(type(pathname) == "string")
106 assert(type(relative_to) == "string" or not relative_to) 117 assert(type(relative_to) == "string" or not relative_to)
107 118
108 relative_to = relative_to or fs.current_dir() 119 relative_to = (relative_to or fs.current_dir()):gsub("[\\/]*$", "")
109 local root, rest = split_root(pathname) 120 local drive, root, rest = split_root(pathname)
110 if root:match("[\\/]$") then 121 if root:match("[\\/]$") then
111 -- It's an absolute path already. 122 -- It's an absolute path already. Ensure is not quoted.
112 return pathname 123 return drive .. root .. rest
113 else 124 else
114 -- It's a relative path, join it with base path. 125 -- It's a relative path, join it with base path.
115 -- This drops drive letter from paths like "C:foo". 126 -- This drops drive letter from paths like "C:foo".
@@ -122,7 +133,8 @@ end
122-- @param pathname string: pathname to use. 133-- @param pathname string: pathname to use.
123-- @return string: The root of the given pathname. 134-- @return string: The root of the given pathname.
124function win32.root_of(pathname) 135function win32.root_of(pathname)
125 return (split_root(fs.absolute_name(pathname))) 136 local drive, root, rest = split_root(fs.absolute_name(pathname))
137 return drive .. root
126end 138end
127 139
128--- Create a wrapper to make a script executable from the command-line. 140--- Create a wrapper to make a script executable from the command-line.