From 129ebf34efa945b2b56a29c80b161414a98757a8 Mon Sep 17 00:00:00 2001 From: Hisham Muhammad Date: Mon, 2 Dec 2019 17:21:20 -0300 Subject: win32: fix split root for quoted absolute path handling --- src/luarocks/fs/unix.lua | 7 ++++++- src/luarocks/fs/win32.lua | 48 +++++++++++++++++++++++++++++------------------ 2 files changed, 36 insertions(+), 19 deletions(-) (limited to 'src') 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) assert(type(pathname) == "string") assert(type(relative_to) == "string" or not relative_to) - relative_to = relative_to or fs.current_dir() + local unquoted = pathname:match("^['\"](.*)['\"]$") + if unquoted then + pathname = unquoted + end + + relative_to = (relative_to or fs.current_dir()):gsub("/*$", "") if pathname:sub(1,1) == "/" then return pathname 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) return cmd.." 2> NUL" end --- Split path into root and the rest. --- Root part consists of an optional drive letter (e.g. "C:") --- and an optional directory separator. -local function split_root(path) +-- Split path into drive, root and the rest. +-- Example: "c:\\hello\\world" becomes "c:" "\\" "hello\\world" +-- if any part is missing from input, it becomes an empty string. +local function split_root(pathname) + local drive = "" local root = "" + local rest = "" - if path:match("^.:") then - root = path:sub(1, 2) - path = path:sub(3) + local unquoted = pathname:match("^['\"](.*)['\"]$") + if unquoted then + pathname = unquoted end - if path:match("^[\\/]") then - root = path:sub(1, 1) - path = path:sub(2) + if pathname:match("^.:") then + drive = pathname:sub(1, 2) + pathname = pathname:sub(3) end - return root, path + if pathname:match("^[\\/]") then + root = pathname:sub(1, 1) + rest = pathname:sub(2) + else + rest = pathname + end + + return drive, root, rest end --- Quote argument for shell processing. Fixes paths on Windows. @@ -59,7 +68,8 @@ function win32.Q(arg) assert(type(arg) == "string") -- Use Windows-specific directory separator for paths. -- Paths should be converted to absolute by now. - if split_root(arg) ~= "" then + local drive, root, rest = split_root(arg) + if root ~= "" then arg = arg:gsub("/", "\\") end if arg == "\\" then @@ -81,7 +91,8 @@ function win32.Qb(arg) assert(type(arg) == "string") -- Use Windows-specific directory separator for paths. -- Paths should be converted to absolute by now. - if split_root(arg) ~= "" then + local drive, root, rest = split_root(arg) + if root ~= "" then arg = arg:gsub("/", "\\") end if arg == "\\" then @@ -105,11 +116,11 @@ function win32.absolute_name(pathname, relative_to) assert(type(pathname) == "string") assert(type(relative_to) == "string" or not relative_to) - relative_to = relative_to or fs.current_dir() - local root, rest = split_root(pathname) + relative_to = (relative_to or fs.current_dir()):gsub("[\\/]*$", "") + local drive, root, rest = split_root(pathname) if root:match("[\\/]$") then - -- It's an absolute path already. - return pathname + -- It's an absolute path already. Ensure is not quoted. + return drive .. root .. rest else -- It's a relative path, join it with base path. -- This drops drive letter from paths like "C:foo". @@ -122,7 +133,8 @@ end -- @param pathname string: pathname to use. -- @return string: The root of the given pathname. function win32.root_of(pathname) - return (split_root(fs.absolute_name(pathname))) + local drive, root, rest = split_root(fs.absolute_name(pathname)) + return drive .. root end --- Create a wrapper to make a script executable from the command-line. -- cgit v1.2.3-55-g6feb