fix(ssh): escape all file paths for the ssh adapter (#353)

* Escape all paths for ssh file changes using `vim.fn.shellescape()`

* Change away from `vim.fn.shellescape` to custom implementation

Really, only escape `'` with `'\\''` so that it will:
- exit the single quote mode
- escape out a single quote character
- and get back into the single quote mode

Also format long line so linter doesn't complain

* Adding doc comments to the shellescape function

* Adding actual words to the doc comment
This commit is contained in:
Kevin Oberlies 2024-04-17 13:19:10 -07:00 committed by GitHub
parent e462a34465
commit 8bb35eb81a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -61,6 +61,12 @@ local function parse_ls_line(line)
return name, type, meta
end
---@param str string String to escape
---@return string Escaped string
local function shellescape(str)
return "'" .. str:gsub("'", "'\\''") .. "'"
end
---@param url oil.sshUrl
---@return oil.sshFs
function SSHFS.new(url)
@ -80,7 +86,7 @@ end
---@param callback fun(err: nil|string)
function SSHFS:chmod(value, path, callback)
local octal = permissions.mode_to_octal_str(value)
self.conn:run(string.format("chmod %s '%s'", octal, path), callback)
self.conn:run(string.format("chmod %s %s", octal, shellescape(path)), callback)
end
function SSHFS:open_terminal()
@ -105,7 +111,9 @@ function SSHFS:realpath(path, callback)
if vim.endswith(abspath, ".") then
abspath = abspath:sub(1, #abspath - 1)
end
self.conn:run(string.format("ls -ald --color=never '%s'", abspath), function(ls_err, ls_lines)
self.conn:run(
string.format("ls -ald --color=never %s", shellescape(abspath)),
function(ls_err, ls_lines)
local type
if ls_err then
-- If the file doesn't exist, treat it like a not-yet-existing directory
@ -119,7 +127,8 @@ function SSHFS:realpath(path, callback)
abspath = util.addslash(abspath)
end
callback(nil, abspath)
end)
end
)
end)
end
@ -131,7 +140,7 @@ local dir_meta = {}
function SSHFS:list_dir(url, path, callback)
local path_postfix = ""
if path ~= "" then
path_postfix = string.format(" '%s'", path)
path_postfix = string.format(" %s", shellescape(path))
end
self.conn:run("LANG=C ls -al --color=never" .. path_postfix, function(err, lines)
if err then
@ -197,40 +206,40 @@ end
---@param path string
---@param callback fun(err: nil|string)
function SSHFS:mkdir(path, callback)
self.conn:run(string.format("mkdir -p '%s'", path), callback)
self.conn:run(string.format("mkdir -p %s", shellescape(path)), callback)
end
---@param path string
---@param callback fun(err: nil|string)
function SSHFS:touch(path, callback)
self.conn:run(string.format("touch '%s'", path), callback)
self.conn:run(string.format("touch %s", shellescape(path)), callback)
end
---@param path string
---@param link string
---@param callback fun(err: nil|string)
function SSHFS:mklink(path, link, callback)
self.conn:run(string.format("ln -s '%s' '%s'", link, path), callback)
self.conn:run(string.format("ln -s %s %s", shellescape(link), shellescape(path)), callback)
end
---@param path string
---@param callback fun(err: nil|string)
function SSHFS:rm(path, callback)
self.conn:run(string.format("rm -rf '%s'", path), callback)
self.conn:run(string.format("rm -rf %s", shellescape(path)), callback)
end
---@param src string
---@param dest string
---@param callback fun(err: nil|string)
function SSHFS:mv(src, dest, callback)
self.conn:run(string.format("mv '%s' '%s'", src, dest), callback)
self.conn:run(string.format("mv %s %s", shellescape(src), shellescape(dest)), callback)
end
---@param src string
---@param dest string
---@param callback fun(err: nil|string)
function SSHFS:cp(src, dest, callback)
self.conn:run(string.format("cp -r '%s' '%s'", src, dest), callback)
self.conn:run(string.format("cp -r %s %s", shellescape(src), shellescape(dest)), callback)
end
function SSHFS:get_dir_meta(url)