sio / bash-complete-partial-path

Enhanced file path completion in bash (like in zsh)
Apache License 2.0
54 stars 2 forks source link

Incorrect escaping of file paths with special characters #5

Closed sio closed 6 years ago

sio commented 6 years ago

Submitted by StrangeAstronomer via reddit

Original report

I have a directory with sub-directories having names with spaces and special characters:

$ ls 
'A Quiet Place (2018) [BluRay] [720p] [YTS.AM]'  'Gemini (2017) [BluRay] [720p] [YTS.AM]'
'Beirut (2018) [WEBRip] [720p] [YTS.AM]'         'Salvation Season 1 Complete 720p HDTV x264 [i_c]'
'Blockers (2018) [BluRay] [720p] [YTS.AM]'       'The Commuter (2018) [BluRay] [720p] [YTS.AM]'
'Disobedience (2017) [BluRay] [720p] [YTS.AM]'   'The Shape Of Water (2017) [BluRay] [1080p] [YTS.AM]'

I try to move one of them by typing mv A<TAB> dvds/ and it completes like this:

$ mv A\\\ Quiet\\\ Place\\\ \\\(2018\\\)\\\ \\\[BluRay\\\]\\\ \\\[720p\\\]\\\ \\\[YTS.AM\\\] dvds
mv: cannot stat 'A\ Quiet\ Place\ \(2018\)\ \[BluRay\]\ \[720p\]\ \[YTS.AM\]': No such file or directory

If I disable bash_completion and re-start bash, it works correctly with mv A<TAB> dvds/ :

$ mv A\ Quiet\ Place\ \(2018\)\ \[BluRay\]\ \[720p\]\ \[YTS.AM\]/ dvds/
$ 

Setting up the test directory

cat <<EOF | while read DIR; do mkdir "$DIR"; done
A Quiet Place (2018) [BluRay] [720p] [YTS.AM]
Gemini (2017) [BluRay] [720p] [YTS.AM]
Beirut (2018) [WEBRip] [720p] [YTS.AM]
Salvation Season 1 Complete 720p HDTV x264 [i_c]
Blockers (2018) [BluRay] [720p] [YTS.AM]
The Commuter (2018) [BluRay] [720p] [YTS.AM]
Disobedience (2017) [BluRay] [720p] [YTS.AM]
The Shape Of Water (2017) [BluRay] [1080p] [YTS.AM]
EOF

The bug has been reproduced by @sio

I have tested this with the latest master (commit 1ac95ed6) and have confirmed the bug exists.

sio commented 6 years ago

Looks like completion results are being escaped twice...

sio commented 6 years ago

The culprit seems to be the upstream bash-completion package and its _filedir function that still gets called before mine. Will change that to conditional call of enhanced completion only in case $COMPREPLY is empty