cli / cli/cli

`cs cp`: inappropriate quoting breaks most use cases

Open
#6,148 8 comments 1 reaction 0 assignees View on GitHub
bug codespaces gh-codespace priority-3
Dominant language
Go
Stars
46.3k
Forks
9k
Avg merge
2d 9h
Merged PRs (30d)
89

Description

### Describe the bug

`gh cs cp` incorrectly wraps single quotes around all remote paths which are interpreted literally by sshd. This means that copying from the codespace is impossible because it looks for e.g. the file with the literal name `'/path/to/my/file'` instead of `/path/to/my/file`. Copying to the codespace only works if you use relative paths and accept the fact that it will always create a file with a mangled quoted wrapped path like `'file'` that you need to fix after copying.

This appears to be due to an attempt to prevent argument injection or mishandling for paths with spaces but the fix doesn't work. I suspect this feature may have been developed on client/server ssh versions which behave differently with respect to quoting rules.

tested with versions:

gh: `version 2.14.4 (2022-08-10)`
server: `OpenSSH_8.4p1 Debian-5+deb11u1, OpenSSL 1.1.1n 15 Mar 2022`
client: `OpenSSH_9.0p1, OpenSSL 1.1.1q 5 Jul 2022`

### Steps to reproduce the behavior

```
Users/carl $ gh --version
gh version 2.14.4 (2022-08-10)
https://github.com/cli/cli/releases/tag/v2.14.4

# demonstrate this file is indeed on the remote server at path /home/vscode/testfile
Users/carl $ gh cs ssh --codespace $CODESPACE_NAME 'ls -la /home/vscode | grep testfile'
-rw-r--r-- 1 vscode vscode 6 Aug 26 09:32 testfile

# cp fails, it's looking for testfile' inside the directory '/home/vscode
Users/carl $ gh cs cp --codespace $CODESPACE_NAME remote:/home/vscode/testfile .
/usr/local/bin/scp: '/home/vscode/testfile': No such file or directory
shell closed: exit status 1

# Other variants where I manually quote don't work either
Users/carl $ gh cs cp --codespace $CODESPACE_NAME remote:'/home/vscode/testfile' .
/usr/local/bin/scp: '/home/vscode/testfile': No such file or directory
shell closed: exit status 1
Users/carl $ gh cs cp --codespace $CODESPACE_NAME remote:"/home/vscode/testfile" .
/usr/local/bin/scp: '/home/vscode/testfile': No such file or directory
shell closed: exit status 1

# Demonstrate again the file is indeed present
Users/carl $ gh cs ssh --codespace $CODESPACE_NAME 'cat /home/vscode/testfile'
hello

# try to send a local file to the codespace using an absolute target path.
Users/carl $ touch blah > localfile && gh cs cp --codespace $CODESPACE_NAME localfile remote:/home/vscode/localfile
/usr/local/bin/scp: dest open "'/home/vscode/localfile'": No such file or directory
/usr/local/bin/scp: failed to upload file localfile to '/home/vscode/localfile'
shell closed: exit status 1

# copy works using relative paths but it mangles the target by wrapping it in literal single quotes
Users/carl $ gh cs cp --codespace $CODESPACE_NAME localfile remote:localfile
localfile
Users/carl $ gh cs ssh --codespace $CODESPACE_NAME 'ls -la /home/vscode | grep file'
-rw-r--r-- 1 vscode vscode 0 Aug 26 09:50 'localfile'
-rw-r--r-- 1 vscode vscode 6 Aug 26 09:32 testfile

### Expected vs actual behavior

file names that don't include spaces are left alone. file names that include spaces are quoted in a way that allows them to be copied with their full name preserved.

### Logs

see above

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.