Bug 2983 - spaces in repository names causing problems
Summary: spaces in repository names causing problems
Status: RESOLVED FIXED
Alias: None
Product: Mercurial
Classification: Unclassified
Component: Mercurial (show other bugs)
Version: unspecified
Hardware: All All
: urgent bug
Assignee: Bugzilla
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-09-03 11:30 UTC by Garrett Mitchener
Modified: 2012-05-13 04:53 UTC (History)
10 users (show)

See Also:
Python Version: ---


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Garrett Mitchener 2011-09-03 11:30 UTC
I drove myself nuts today re-organizing some of my projects using hg.  I had
trouble using subrepositories with spaces in their names, and I think it has
to do with the way ssh is called.  I didn't see any documentation about
repositories with spaces in their names, so I checked out the development
version of hg, and found this:

sshrepo.py line 60:

        cmd = '%s %s "%s -R %s serve --stdio"'
        cmd = cmd % (sshcmd, args, remotecmd, self.path)

The problem is that if self.path contains spaces (as in "my repo"), then
when you do something like

hg clone "ssh://server/my repo"

the command executed on the remote machine is literally

hg -R my repo serve --stdio

and you get an error about remote: hg: unknown command 'repo'

What I need is for the remote command to be something like

hg -R 'my repo' serve --stdio

I've tried putting quote marks in various places on the command line and
configuration files (without changing the source code) and had no success
getting it to work.  I think the only way to fix it is to quote the path in
sshrepo.py, something like this:

        cmd = "%s %s \"%s -R '%s' serve --stdio\""
        cmd = cmd % (sshcmd, args, remotecmd, self.path)

but I'm not sure exactly how to test it.  (I'm new to hg)
Comment 1 Frank Kingswood 2011-09-05 06:20 UTC
There is util.shellquote to do that.

But IIRC ssh quoting is a bit weird, being unquoted twice.

For example, if I do
    ssh server mkdir "a b"
then it will run the command
    mkdir a b
on the server, and create two directories.

To get the directory with a space in the name I must do
    ssh server mkdir "'a b'"
Comment 2 Garrett Mitchener 2011-09-05 07:46 UTC
I'm also curious about intended behavior for hg with respect to quoting and
shell interpretation.  Is something like

hg clone 'ssh://server/$PROJECT/'

supposed to work?  That is, when we get to

ssh server -c "hg -R $PROJECT ..."

is the shell on the server expected to insert PROJECT from the environment
table?  If directories are quoted so as to forbid any transformation by the
shell on the server, it would probably fix my problem with spaces in
directory names, but will it break a "feature" like the above that someone
might be relying on?

For that matter, is there a security hole here?  As in, what if you try:

hg clone "ssh://server/project;rm%20-rf%20/"

will it actually evaluate the rm -rf /
Comment 3 Frank Kingswood 2011-09-05 07:55 UTC
If you wanted this then you could do
hg clone 'ssh://server/'$PROJECT'/'

I can verify that running
   hg clone --debug 'ssh://server/some.dir;logger -- bah/' -v
actually does call the logger command.

Now this may not actually be any worse then you could do with your ssh login
key anyway. Fixing this on the client side (with quoting) may make it a bit
less likely to be accidentally issued, but would not stop any actual abuse.

I think the hg-ssh wrapper script probably catches this.
Comment 4 Frank Kingswood 2011-09-13 02:58 UTC
Please send your change to the mailing list fixing the quoting (using
shellquote).
Comment 5 Garrett Mitchener 2011-09-15 09:42 UTC
I'm working on it.  I rearranged the formation of the ssh commands using
util.shellquote, but now if I do, say

hg clone 'ssh://localhost//tmp/Foo Bar'

I get a directory called Foo%20Bar, which isn't really what should happen. 
Instead, it should be like this:

hg clone '/tmp/Foo Bar'

which creates a directory called 'Foo Bar'

And I see comments elsewhere in the ssh code about how paths aren't being
un-escaped in case there's a / embedded as a %##.  I'm not sure what else
needs to be changed to fix the output path.  I'll keep working on it though.
Comment 6 Matt Mackall 2011-09-15 09:56 UTC
On the remote host, we want a string like:

$ hg -R 'with a space' ...

which means we want an ssh command like this (single quoted string with
single quotes inside):

$ ssh host 'hg -R '\''with a space'\' ...'

which we can achieve in Python like this (escaped escapes):

>>> a = "ssh mercurial 'hg -R '\\''%s'\\'' tip'" % "with a space"
>>> os.system(a)
abort: repository with a space not found!

Hmmm, perhaps that message needs some quotes!
Comment 7 HG Bot 2011-11-30 18:00 UTC
Fixed by http://selenic.com/repo/hg/rev/d8fa35c28335
Mads Kiilerich <mads@kiilerich.com>
ssh: quote remote paths (issue2983)

(please test the fix)
Comment 8 Thomas Arendsen Hein 2011-12-07 03:01 UTC
This currently breaks hg-ssh, because it does not expect the extra quotes.
Additionally it is inconsistent with other unix tools like rsync and scp,
which require double escaping, too:

$ rsync file other.example.com:'foo\ bar'/
puts file in "$HOME/foo bar/file"

$ rsync file other.example.com:'foo bar'/
puts file in "$HOME/foo"

$ scp file other.example.com:'foo bar'/
aborts with "scp: ambiguous target"

$ scp file other.example.com:'foo\ bar'/
puts file in "$HOME/foo bar/file"
Comment 9 Thomas Arendsen Hein 2011-12-07 03:16 UTC
Note that I'm not saying Mercurial should behave like rsync and scp here,
but when introducing different behaviour it needs to be done carefully.

I suggest that quoting/escaping should only done where needed, to keep
compatibility with existing installations of hg-ssh, hgsh, mercurial-server,
hg-login, hg-gateway and friends.
Comment 10 Garrett Mitchener 2011-12-07 08:09 UTC
Sort of.  I think that if

hg clone '/path/foo bar'

clones a repository into 'foo bar', then

hg clone 'ssh:server/foo bar'

should do the same.  Or if that's not possible, then

hg clone ssh:server/'foo\ bar'

ought to work.

Here's what I see with hg 1.9.2 as distributed with fedora 16

$ hg clone 'ssh://grograman/tmp/foo bar'
remote: hg: unknown command 'bar'
abort: no suitable response from remote hg!

$ hg clone ssh://grograman/tmp/foo%20bar
remote: hg: unknown command 'bar'
abort: no suitable response from remote hg!

$ hg clone 'ssh://grograman/tmp/foo\ bar'
destination directory: foo%5C%20bar
requesting all changes
adding changesets
adding manifests
adding file changes
added 8 changesets with 8 changes to 1 files
updating to branch default
1 files updated, 0 files merged, 0 files removed, 0 files unresolved

which puts the repository into foo%5C%20bar.  Same with "" quotes. Same if I 
put the quotes just around 'foo\ bar'.  None of this consistent with the 
rsync or ssh examples you posted.

When I use the hg development version,

$ hg clone 'ssh://grograman/tmp/foo bar'

puts the repository into foo%20bar, again, not quite right.

$ hg clone 'ssh://grograman/tmp/foo\ bar'
remote: abort: There is no Mercurial repository here (.hg not found)!
abort: no suitable response from remote hg!

So it's not so much the quoting I have to do to the ssh URL, but whether the 
destination on the local machine is what's expected.
Comment 11 Martin Geisler 2011-12-08 04:26 UTC
This issue also prevents people from using SSH with Bitbucket:

% hg incoming --debug
running ssh mg@bitbucket.org ''\''hg'\'' -R '\''mg/test'\'' serve --stdio'
sending hello command
sending between command
remote: conq: invalid command syntax.
abort: no suitable response from remote hg!

It also prevents crew from working with the crew server.
Comment 12 Martin Geisler 2011-12-08 04:36 UTC
I've made Bitbucket aware of the issue:

https://bitbucket.org/site/master/issue/3366/getting-remote-conq-invalid-
command-syntax
Comment 13 HG Bot 2011-12-08 17:00 UTC
Fixed by http://selenic.com/repo/hg/rev/86fc364ca5f8
Mads Kiilerich <mads@kiilerich.com>
sshrepo: don't quote obviously safe strings (issue2983)

(please test the fix)
Comment 14 Garrett Mitchener 2011-12-09 08:34 UTC
I'm getting the same unfortunate behavior in my test cases: The local directory still 
comes out with % codes in its name when you clone a repository over ssh.
Comment 15 Thomas Arendsen Hein 2011-12-09 08:57 UTC
Garrett, can you file a separate issue for the % codes on the local side?

Regarding this issue: Now it works much better, but I added some more chars,
especially the + was missing.
See http://hg.intevation.org/mercurial/crew/rev/be43234a6d60
Comment 16 Garrett Mitchener 2011-12-09 09:15 UTC
I just used 'make a copy' to create issue 3145 about the % code problem, so I 
guess we'll use this issue to deal with the way to quote paths and such when 
sending commands over ssh.
Comment 17 HG Bot 2011-12-09 16:00 UTC
Fixed by http://selenic.com/repo/hg/rev/be43234a6d60
Thomas Arendsen Hein <thomas@intevation.de>
sshrepo: add more safe characters (issue2983)

(please test the fix)
Comment 18 Bugzilla 2012-05-12 09:23 UTC

--- Bug imported by bugzilla@serpentine.com 2012-05-12 09:23 EDT  ---

This bug was previously known as _bug_ 2983 at http://mercurial.selenic.com/bts/issue2983