Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(rsync,ssh): do not overescape spaces in remote filenames #910

Open
wants to merge 3 commits into
base: main
Choose a base branch
from

Conversation

Rogach
Copy link
Contributor

@Rogach Rogach commented Mar 29, 2023

Fixes #848.

If a remote machine contains a file named a b, completing rsync command results in rsync remote:a\\\ b, which results in rsync failing to find the file.

This commit removes the extra slashes, and now completion results in rsync remote:a\ b.

scp somehow accepts both variants, so this change won't break it.

@akinomyoga
Copy link
Collaborator

Can we detect the rsync version and switch the behavior depending on whether the version is lower than 3.2.4 or not? 3.2.4 (2022-04) seems still new, so we expect there are still two different types of rsync in the market.

@Rogach
Copy link
Contributor Author

Rogach commented Mar 29, 2023

Sure, but that'll require an extra call to rsync --version and an ugly extra argument to _comp_xfunc_ssh_scp_remote_files.

@akinomyoga
Copy link
Collaborator

Do you have a better solution?

@Rogach
Copy link
Contributor Author

Rogach commented Mar 29, 2023

I've added a commit with the rsync version check.

However, if I were a maintainer, I'd much prefer the simpler solution of just working with the latest version. By the time bash-completion 2.12 is released and propagates to the distributions, it is likely that rsync will also be updated in those distributions. It would be strange if bash-completion were updated while rsync remained on an older version.

I've done a quick check on the distributions:

  • Ubuntu 22.04 LTS has rsync 3.2.7 (after security update)
  • Ubuntu 22.10 has rsync 3.2.7
  • Debian stable has rsync 3.2.3
  • Debian testing has rsync 3.2.7
  • Fedora 36-38 has rsync 3.2.7

Arch Linux, of course, has the latest version. I was actually quite surprised to find out that Arch still uses bash-completion from 2020.

From a maintenance perspective, I believe it would be much better not to check the rsync version, as this significantly complicates the code.

Copy link
Collaborator

@akinomyoga akinomyoga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for updating the PR.

I have a question. The function _comp_xfunc_ssh_scp_remote_files seems to be also called from the completions for other commands ssh and sshfs. I guess we want to keep the original behavior for these commands. Or did these commands also change its interpretation of the escapes?

The others are cosmetic.

completions/rsync Outdated Show resolved Hide resolved
completions/rsync Outdated Show resolved Hide resolved
completions/rsync Outdated Show resolved Hide resolved
completions/ssh Outdated Show resolved Hide resolved
@Rogach
Copy link
Contributor Author

Rogach commented Mar 29, 2023

I have a question. The function _comp_xfunc_ssh_scp_remote_files seems to be also called from the completions for other commands ssh and sshfs. I guess we want to keep the original behavior for these commands. Or did these commands also change its interpretation of the escapes?

It was my understanding that they accept both versions of these arguments (tested on my versions), but I'm not sure for how long they had this behavior. I'll invert the check so that we only change the behavior for the newer rsyncs.

@akinomyoga
Copy link
Collaborator

akinomyoga commented Mar 29, 2023

However, if I were a maintainer, I'd much prefer the simpler solution of just working with the latest version. By the time bash-completion 2.12 is released and propagates to the distributions, it is likely that rsync will also be updated in those distributions. It would be strange if bash-completion were updated while rsync remained on an older version.

Users are allowed to anytime download the latest version of bash-completion from GitHub independently of the OS distributions.

From a maintenance perspective, I believe it would be much better not to check the rsync version, as this significantly complicates the code.

Ubuntu LTS 18.04 will soon expire, but LTS 20.04 (with rsync 3.1.3) will still continue to be maintained until 2025-04. That's the idea of LTS. Also, we perform CI tests under Debian 10 (w/ rsync 3.1.3), CentOS 7 (w/ rsync 3.1.2), and Ubuntu 14.04 (w/ rsync ???). We actually support as old Bash as 4.2, (which is the reason that we have tests in Ubuntu 14.04).

@akinomyoga
Copy link
Collaborator

It was my understanding that they accept both versions of these arguments (tested on my versions), but I'm not sure for how long they had this behavior. I'll invert the check so that we only change the behavior for the newer rsyncs.

Thank you. I think that's safer for now.

@Rogach Rogach force-pushed the pr/rsync-fix-space-escapes branch from c944277 to 1d72577 Compare March 29, 2023 12:36
Copy link
Collaborator

@akinomyoga akinomyoga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for addressing all the points. Two points are raised by shfmt of the CI.

completions/rsync Outdated Show resolved Hide resolved
completions/ssh Outdated Show resolved Hide resolved
Copy link
Collaborator

@akinomyoga akinomyoga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are additional suggestions/comments.

completions/rsync Outdated Show resolved Hide resolved
completions/rsync Outdated Show resolved Hide resolved
@Rogach Rogach force-pushed the pr/rsync-fix-space-escapes branch from 1d72577 to e02ff4e Compare March 30, 2023 09:04
completions/rsync Outdated Show resolved Hide resolved
@Rogach Rogach force-pushed the pr/rsync-fix-space-escapes branch from e02ff4e to 03eb3ab Compare March 30, 2023 09:31
Copy link
Owner

@scop scop left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Left some comments.

Also, I think at least _comp_cmd_rsync__vercomp would deserve some tests.

completions/rsync Outdated Show resolved Hide resolved
completions/ssh Outdated
@@ -434,8 +434,11 @@ _comp_cmd_scp__path_esc='[][(){}<>"'"'"',:;^&!$=?`\\|[:space:]]'
# Complete remote files with ssh. If the first arg is -d, complete on dirs
# only. Returns paths escaped with three backslashes.
# shellcheck disable=SC2120
# @param $1 `no-overescape` if we should use 1 backslash for escaping instead of 3
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even though I agree that the original escape seems a bit overdoing it, it is the traditional/standard one that's been there for a long time, and it is still the say ssh does it -- rsync is kind of a "guest" here. In that sense I'd prefer a more neutral variable name here.

Also, requiring a positional boolean-like parameter to have a specific value like here feels somewhat unconventional. Making it an option (i.e. dash prefixed, no value required as it's a boolean) would be more in line with rest of the codebase.

Copy link
Collaborator

@akinomyoga akinomyoga Apr 2, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, I overlooked the fact that $1 is already used for -d.

edit:

I think the added documentation line of @param should be put before the shellcheck line.

I think we should test the new behavior of scp_remote_files too.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In that sense I'd prefer a more neutral variable name here.

What name would you suggest?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should test the new behavior of scp_remote_files too.

How shall I approach that? It calls ssh inside to fetch completions, so simply calling the function as it is now won't work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see there's a mechanism with LIVE_HOST in test_scp, however to test remote escaping I need to know list of filenames that are present on the remote machine, and at least one of the files needs to have a space in it.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should test the new behavior of scp_remote_files too.

How shall I approach that? It calls ssh inside to fetch completions, so simply calling the function as it is now won't work.

This is a good question. I confess that I haven't thought about it deeply.

Also, I haven't recognized the LIVE_HOST approach used by test_scp.py until now. Hmm, I'm not sure how LIVE_HOST is set up in the repository. There doesn't seem to be a ssh config file that contains bash_completion as a hostname:

(venv) [murase@chatoyancy 1 bash-completion]$ grep bash_completion $(git ls-files | grep config)
.pre-commit-config.yaml:        files: ^(bash_completion(\.d/[^/]+\.bash)?|completions/.+|test/(config/bashrc|update-test-cmd-list)|.+\.sh(\.in)?)$
.pre-commit-config.yaml:        files: ^(bash_completion(\.d/[^/]+\.bash)?|completions/.+|test/(config/bashrc|update-test-cmd-list)|.+\.sh(\.in)?)$
bash-completion-config.cmake.in:set (BASH_COMPLETION_COMPATDIR "@sysconfdir@/bash_completion.d")
doc/configuration.md:Sourced late by `bash_completion`, pretty much after everything else.
doc/configuration.md:and override ones installed by bash_completion. Defaults to
doc/configuration.md:`~/.bash_completion` if unset or null.
doc/configuration.md:### `$XDG_CONFIG_HOME/bash_completion`
doc/configuration.md:Sourced by the `bash_completion.sh` `profile.d` script. This file is
doc/configuration.md:compatibility completion files that are loaded eagerly from `bash_completion`
doc/configuration.md:use are `/etc/bash_completion.d`, and `bash_completion.d` relative to
doc/configuration.md:`bash_completion` location.
doc/configuration.md:with this pattern will not be sourced by `bash_completion` at its load time.
test/config/bashrc:# installed via the same PATH expansion in `bash_completion.have()'
test/config/bashrc:# For clean test state, avoid sourcing user's ~/.bash_completion
test/config/bashrc:export BASH_COMPLETION_COMPAT_DIR="$SRCDIRABS/../bash_completion.d"

Another way is to prepare a mock command/function named ssh, which mimics the command results (as discussed in #573). This can be an option if we actually do not have the working LIVE_HOST.

@scop Are there any references on what is LIVE_HOST used in test_scp.py and how to set it up?

Copy link

@jucor jucor Oct 8, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@scop I realise this is the current comment requested that's still blocking. However, now that the latest rsync has a bigger install base, the problem (that this PR would fix) is spreading. Would you consider merging it even without this test, to pull users out of their misery, please?

completions/rsync Outdated Show resolved Hide resolved
completions/ssh Outdated Show resolved Hide resolved
completions/ssh Outdated Show resolved Hide resolved
@Rogach Rogach force-pushed the pr/rsync-fix-space-escapes branch from 03eb3ab to 9022d56 Compare April 3, 2023 10:43
@Rogach
Copy link
Contributor Author

Rogach commented Apr 3, 2023

Applied changes according to comments.

Regarding scp_remote_files test - added tests that expect LIVE_HOST remote files to include file spaces in filename.txt.

@Rogach Rogach force-pushed the pr/rsync-fix-space-escapes branch 3 times, most recently from 9708e3a to 87f3e60 Compare April 3, 2023 11:00
Copy link
Collaborator

@akinomyoga akinomyoga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for updating the PR. Here are the comments on the new part.

completions/ssh Outdated Show resolved Hide resolved
completions/ssh Outdated Show resolved Hide resolved
test/t/test_rsync.py Outdated Show resolved Hide resolved
completions/ssh Outdated Show resolved Hide resolved
@jucor
Copy link

jucor commented Oct 8, 2023

I got bitten by this problem today. Would it be possible to get this merged, please?
This is also referred in https://www.reddit.com/r/pop_os/comments/124jmp1/synchronizing_rsync_so_it_only_singlequotes/
Thanks a lot!

@akinomyoga
Copy link
Collaborator

rebased. The test using LIVE_HOST is not fixed.

Rogach and others added 3 commits May 13, 2024 20:37
Fixes scop#848.

If a remote machine contains a file named `a b`, completing rsync
command results in `rsync remote:a\\\ b`, which results in rsync
failing to find the file.

This commit removes the extra slashes, and now completion results in
`rsync remote:a\ b`.

scp somehow accepts both variants, so this change won't break it.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

rsync ssh remote paths are double-escaped (incorrect since rsync 3.2.4)
4 participants