Skip to content

Commit fc9758a

Browse files
committed
fix(scp): work around incomplete triple backslashes for remote paths
1 parent ce45cc9 commit fc9758a

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

completions/ssh

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,21 @@ _comp_xfunc_scp_compgen_remote_files()
541541
local REPLY=$cur
542542
if [[ ! $_less_escaping ]]; then
543543
# unescape (3 backslashes to 1 for chars we escaped)
544-
REPLY=$(command sed -e 's/\\\\\\\('"$_comp_cmd_scp__path_esc"'\)/\\\1/g' <<<"$REPLY")
544+
#
545+
# Note: We want to do the following, but POSIX BRE does not support \|:
546+
#
547+
# REPLY=$(command sed -e 's/\\\\\\\('"$_comp_cmd_scp__path_esc"'\|$\)/\\\1/g' <<<"$REPLY")
548+
#
549+
# Note: We need to store \\\\\\ in a variable to work around "shopt -s
550+
# compat31".
551+
local _tail=$REPLY _regex_triple_backslashes='\\\\\\('$_comp_cmd_scp__path_esc'|$)(.*)$'
552+
REPLY=
553+
while [[ $_tail && $_tail =~ $_regex_triple_backslashes ]]; do
554+
# shellcheck disable=SC1003
555+
REPLY=${_tail::${#_tail}-${#BASH_REMATCH}}'\'${BASH_REMATCH[1]}
556+
_tail=${BASH_REMATCH[2]}
557+
done
558+
REPLY+=$_tail
545559
fi
546560
_comp_dequote_incomplete "$REPLY"
547561
local cur_val=${REPLY-}

test/t/test_scp.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,15 @@ def test_remote_path_with_backslash(self, bash):
133133
[r"abc\ def.txt", r"abc\\\ def.txt"]
134134
) or completion == sorted([r"abc\\\ def.txt", r"abc\\\\\\\ def.txt"])
135135

136+
def test_remote_path_with_backslash_2(self, bash):
137+
assert_bash_exec(
138+
bash, r"ssh() { [[ $1 == abc ]]; printf '%s\n' 'abc OK'; }"
139+
)
140+
completion = assert_complete(bash, "scp remote_host:abc\\\\\\")
141+
assert_bash_exec(bash, "unset -f ssh")
142+
143+
assert completion == "OK"
144+
136145
def test_xfunc_remote_files(self, live_pwd, bash):
137146
def prefix_paths(prefix, paths):
138147
return [f"{prefix}{path}" for path in paths]

0 commit comments

Comments
 (0)