Skip to content

Commit 2040a58

Browse files
committed
fix(java,rsync,scp): handle quoted space in filepaths properly
Filenames containing a special character are not properly completed [1]. These completions generate filenames by pathname expanaion using $cur. However, $cur contains the word on the command line including quotaing, such as cur='file\ with\ space.txt' and cur='"a b c.txt"'. This patch obtains the value of "cur" using _comp_dequote. [1] #1232 This patch also fixes a similar case in completions/java.
1 parent 538838c commit 2040a58

File tree

4 files changed

+36
-9
lines changed

4 files changed

+36
-9
lines changed

completions/java

+6-2
Original file line numberDiff line numberDiff line change
@@ -113,12 +113,16 @@ _comp_cmd_java__packages()
113113
_comp_cmd_java__find_sourcepath || return 0
114114
local -a sourcepaths=("${REPLY[@]}")
115115

116+
local REPLY
117+
_comp_dequote "$cur" || REPLY=$cur
118+
local cur_val=${REPLY-}
119+
116120
# convert package syntax to path syntax
117-
local cur=${cur//.//}
121+
local cur_val=${cur_val//.//}
118122
# parse each sourcepath element for packages
119123
for i in "${sourcepaths[@]}"; do
120124
if [[ -d $i ]]; then
121-
_comp_expand_glob files '"$i/$cur"*' || continue
125+
_comp_expand_glob files '"$i/$cur_val"*' || continue
122126
_comp_split -la COMPREPLY "$(
123127
command ls -F -d "${files[@]}" 2>/dev/null |
124128
command sed -e 's|^'"$i"'/||'

completions/ssh

+14-7
Original file line numberDiff line numberDiff line change
@@ -522,13 +522,16 @@ _comp_xfunc_scp_compgen_remote_files()
522522
done
523523

524524
# remove backslash escape from the first colon
525-
local cur=${cur/\\:/:}
526-
527-
local _userhost=${cur%%?(\\):*}
528-
local _path=${cur#*:}
525+
local REPLY=$cur
526+
if [[ ! $_less_escaping ]]; then
527+
# unescape (3 backslashes to 1 for chars we escaped)
528+
REPLY=$(command sed -e 's/\\\\\\\('"$_comp_cmd_scp__path_esc"'\)/\\\1/g' <<<"$REPLY")
529+
fi
530+
_comp_dequote "$REPLY"
531+
local cur_val=${REPLY-}
529532

530-
# unescape (3 backslashes to 1 for chars we escaped)
531-
_path=$(command sed -e 's/\\\\\\\('"$_comp_cmd_scp__path_esc"'\)/\\\1/g' <<<"$_path")
533+
local _userhost=${cur_val%%:*}
534+
local _path=${cur_val#*:}
532535

533536
# default to home dir of specified user on remote host
534537
if [[ ! $_path ]]; then
@@ -566,8 +569,12 @@ _comp_xfunc_scp_compgen_local_files()
566569
shift
567570
fi
568571

572+
local REPLY
573+
_comp_dequote "$cur" || REPLY=$cur
574+
local cur_val=${REPLY-}
575+
569576
local files
570-
_comp_expand_glob files '"$cur"*' || return 0
577+
_comp_expand_glob files '"$cur_val"*' || return 0
571578
_comp_compgen -RU files split -l ${1:+-P "$1"} -- "$(
572579
command ls -aF1dL "${files[@]}" 2>/dev/null |
573580
_comp_cmd_scp__escape_path "$_dirsonly"

test/t/test_rsync.py

+8
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,11 @@ def test_remote_path_with_spaces(self, bash):
7373
completion == r"\ in\ filename.txt"
7474
or completion == r"\\\ in\\\ filename.txt"
7575
)
76+
77+
@pytest.mark.complete("rsync -na spaced\\ ", cwd="scp")
78+
def test_local_path_with_spaces(self, completion):
79+
"""This function tests xfunc _comp_xfunc_scp_compgen_local_files, which
80+
is defined in completions/ssh, through the rsync interface. We reuse
81+
the fixture directory for the test of the scp completion.
82+
"""
83+
assert completion

test/t/test_scp.py

+8
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,11 @@ def test_local_path_mark_1(self, bash, tmpdir_mkfifo):
174174
bash, "scp local_path_1-", cwd=tmpdir_mkfifo
175175
)
176176
assert completion == "pipe"
177+
178+
@pytest.mark.complete("scp spa", cwd="scp")
179+
def test_local_path_with_spaces_1(self, completion):
180+
assert completion == "ced\\ \\ conf"
181+
182+
@pytest.mark.complete("scp spaced\\ ", cwd="scp")
183+
def test_local_path_with_spaces_2(self, completion):
184+
assert completion == "\\ conf"

0 commit comments

Comments
 (0)