From ef0653619052d02035e2cf6cc0b95effc543f3b1 Mon Sep 17 00:00:00 2001 From: Philipp Janda Date: Mon, 14 Oct 2013 18:28:34 +0200 Subject: better shell escaping on windows --- src/luarocks/fs/lua.lua | 12 ++++++++++++ src/luarocks/fs/win32.lua | 47 +++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 6 deletions(-) diff --git a/src/luarocks/fs/lua.lua b/src/luarocks/fs/lua.lua index 0e81d877..119fcbe4 100644 --- a/src/luarocks/fs/lua.lua +++ b/src/luarocks/fs/lua.lua @@ -42,6 +42,18 @@ function Q(arg) return "'" .. arg:gsub("'", "'\\''") .. "'" end +--- Quote argument for shell processing in batch files/scripts. +-- By default calls fs.Q() +-- @param arg string: Unquoted argument. +-- @return string: Quoted argument. +function Qb(arg) + assert(type(arg) == "string") + + -- only strange platforms (aka Windows) need special + -- escape handling for scripts/batch files + return fs.Q(arg) +end + --- Test is file/dir is writable. -- Warning: testing if a file/dir is writable does not guarantee -- that it will remain writable and therefore it is no replacement diff --git a/src/luarocks/fs/win32.lua b/src/luarocks/fs/win32.lua index 4a105e8d..f7555439 100644 --- a/src/luarocks/fs/win32.lua +++ b/src/luarocks/fs/win32.lua @@ -16,18 +16,53 @@ function quiet(cmd) return cmd.." 2> NUL 1> NUL" end + +local win_escape_chars = { + ["%"] = "%%", + ['"'] = '\\"', +} + +local function q_escaper(bs, q) + return ("\\"):rep(2*#bs-1) .. (q or "\\") +end + +local function p_escaper(bs) + return bs .. bs .. '"%"' +end + --- Quote argument for shell processing. Fixes paths on Windows. --- Adds single quotes and escapes. +-- Adds double quotes and escapes. -- @param arg string: Unquoted argument. -- @return string: Quoted argument. function Q(arg) assert(type(arg) == "string") -- Quote DIR for Windows - if arg:match("^[%.a-zA-Z]?:?[\\/]") then - return '"' .. arg:gsub("/", "\\"):gsub('"', '\\"') .. '"' - end + if arg:match("^[%.a-zA-Z]?:?[\\/]") then + arg = arg:gsub("/", "\\") + end -- URLs and anything else - return '"' .. arg:gsub('"', '\\"') .. '"' + arg = arg:gsub('(\\+)(")', q_escaper) + arg = arg:gsub('(\\+)$', q_escaper) + arg = arg:gsub('"', win_escape_chars) + arg = arg:gsub('(\\*)%%', p_escaper) + return '"' .. arg .. '"' +end + +--- Quote argument for shell processing in batch files. +-- Adds double quotes and escapes. +-- @param arg string: Unquoted argument. +-- @return string: Quoted argument. +function Qb(arg) + assert(type(arg) == "string") + -- Quote DIR for Windows + if arg:match("^[%.a-zA-Z]?:?[\\/]") then + arg = arg:gsub("/", "\\") + end + -- URLs and anything else + arg = arg:gsub('(\\+)(")', q_escaper) + arg = arg:gsub('(\\+)$', q_escaper) + arg = arg:gsub('[%%"]', win_escape_chars) + return '"' .. arg .. '"' end --- Return an absolute pathname from a potentially relative one. @@ -73,7 +108,7 @@ function wrap_script(file, dest, name, version) local lua = dir.path(cfg.variables["LUA_BINDIR"], cfg.lua_interpreter) local ppaths = "package.path="..util.LQ(lpath..";").."..package.path; package.cpath="..util.LQ(lcpath..";").."..package.cpath" local addctx = "luarocks.loader.add_context("..util.LQ(name)..","..util.LQ(version)..")" - wrapper:write(fs.Q(lua)..' -e '..fs.Q(ppaths)..' -lluarocks.loader -e '..fs.Q(addctx)..' '..fs.Q(file)..' %*\n') + wrapper:write(fs.Qb(lua)..' -e '..fs.Qb(ppaths)..' -lluarocks.loader -e '..fs.Qb(addctx)..' '..fs.Qb(file)..' %*\n') wrapper:close() return true end -- cgit v1.2.3-55-g6feb