diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2013-09-27 20:48:13 +0700 |
---|---|---|
committer | Jonathan Nieder <jrnieder@gmail.com> | 2013-09-27 14:47:49 -0700 |
commit | 8d3d28f5dba94a15a79975e4adc909c295c80d80 (patch) | |
tree | 310219cae29092db240094ab7719336c6b38f5c5 | |
parent | clone: allow cloning local paths with colons in them (diff) | |
download | tgif-8d3d28f5dba94a15a79975e4adc909c295c80d80.tar.xz |
clone: tighten "local paths with colons" check a bit
commit 6000334 (clone: allow cloning local paths with colons in them -
2013-05-04) made it possible to specify a path that has colons in it
without file://, e.g. ../foo:bar/somewhere. But the check was a bit
sloppy.
Consider the url '[foo]:bar'. The '[]' unwrapping code will turn the
string to 'foo\0:bar'. In effect this new string is the same as
'foo/:bar' in the check "path < strchrnul(host, '/')", which mistakes
it for a local path (with '/' before the first ':') when it's actually
not.
So disable the check for '/' before ':' when the URL has been mangled
by '[]' unwrapping.
[jn: with tests from Jeff King]
Noticed-by: Morten Stenshorne <mstensho@opera.com>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
-rw-r--r-- | connect.c | 2 | ||||
-rwxr-xr-x | t/t5601-clone.sh | 46 |
2 files changed, 46 insertions, 2 deletions
@@ -550,7 +550,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig, path = strchr(end, c); if (path && !has_dos_drive_prefix(end)) { if (c == ':') { - if (path < strchrnul(host, '/')) { + if (host != url || path < strchrnul(host, '/')) { protocol = PROTO_SSH; *path++ = '\0'; } else /* '/' in the host part, assume local path */ diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index 0629149edd..a3e3d489ec 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -280,9 +280,53 @@ test_expect_success 'clone checking out a tag' ' test_cmp fetch.expected fetch.actual ' +test_expect_success 'setup ssh wrapper' ' + write_script "$TRASH_DIRECTORY/ssh-wrapper" <<-\EOF && + echo >>"$TRASH_DIRECTORY/ssh-output" "ssh: $*" && + # throw away all but the last argument, which should be the + # command + while test $# -gt 1; do shift; done + eval "$1" + EOF + + GIT_SSH="$TRASH_DIRECTORY/ssh-wrapper" && + export GIT_SSH && + export TRASH_DIRECTORY +' + +clear_ssh () { + >"$TRASH_DIRECTORY/ssh-output" +} + +expect_ssh () { + { + case "$1" in + none) + ;; + *) + echo "ssh: $1 git-upload-pack '$2'" + esac + } >"$TRASH_DIRECTORY/ssh-expect" && + (cd "$TRASH_DIRECTORY" && test_cmp ssh-expect ssh-output) +} + +test_expect_success 'cloning myhost:src uses ssh' ' + clear_ssh && + git clone myhost:src ssh-clone && + expect_ssh myhost src +' + test_expect_success NOT_MINGW,NOT_CYGWIN 'clone local path foo:bar' ' + clear_ssh && cp -R src "foo:bar" && - git clone "./foo:bar" foobar + git clone "./foo:bar" foobar && + expect_ssh none +' + +test_expect_success 'bracketed hostnames are still ssh' ' + clear_ssh && + git clone "[myhost:123]:src" ssh-bracket-clone && + expect_ssh myhost:123 src ' test_done |