Skip to content

Commit 36f7b53

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 fe46238 commit 36f7b53

File tree

4 files changed

+35
-8
lines changed

4 files changed

+35
-8
lines changed

completions/java

Lines changed: 5 additions & 1 deletion
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"
118+
local cur_val=${REPLY-}
119+
116120
# convert package syntax to path syntax
117121
local cur=${cur//.//}
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

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -521,13 +521,16 @@ _comp_xfunc_scp_compgen_remote_files()
521521
done
522522

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

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

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

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

test/t/test_rsync.py

Lines changed: 8 additions & 0 deletions
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

Lines changed: 8 additions & 0 deletions
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)