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>

Nguyễn Thái Ngọc Duy committed Sep 27, 2013 at 20:48 UTC 8d3d28f5dba94a15a79975e4adc909c295c80d80
2 files changed +46 -2
connect.c
+1 -1
@@ -550,7 +550,7 @@ struct child_process *git_connect(int fd[2], const char *url_orig,
550 path = strchr(end, c);
551 if (path && !has_dos_drive_prefix(end)) {
552 if (c == ':') {
553 - if (path < strchrnul(host, '/')) {
553 + if (host != url || path < strchrnul(host, '/')) {
554 protocol = PROTO_SSH;
555 *path++ = '\0';
556 } else /* '/' in the host part, assume local path */
t/t5601-clone.sh
+45 -1
@@ -280,9 +280,53 @@ test_expect_success 'clone checking out a tag' '
280 test_cmp fetch.expected fetch.actual
281 '
282
283 +test_expect_success 'setup ssh wrapper' '
284 + write_script "$TRASH_DIRECTORY/ssh-wrapper" <<-\EOF &&
285 + echo >>"$TRASH_DIRECTORY/ssh-output" "ssh: $*" &&
286 + # throw away all but the last argument, which should be the
287 + # command
288 + while test $# -gt 1; do shift; done
289 + eval "$1"
290 + EOF
291 +
292 + GIT_SSH="$TRASH_DIRECTORY/ssh-wrapper" &&
293 + export GIT_SSH &&
294 + export TRASH_DIRECTORY
295 +'
296 +
297 +clear_ssh () {
298 + >"$TRASH_DIRECTORY/ssh-output"
299 +}
300 +
301 +expect_ssh () {
302 + {
303 + case "$1" in
304 + none)
305 + ;;
306 + *)
307 + echo "ssh: $1 git-upload-pack '$2'"
308 + esac
309 + } >"$TRASH_DIRECTORY/ssh-expect" &&
310 + (cd "$TRASH_DIRECTORY" && test_cmp ssh-expect ssh-output)
311 +}
312 +
313 +test_expect_success 'cloning myhost:src uses ssh' '
314 + clear_ssh &&
315 + git clone myhost:src ssh-clone &&
316 + expect_ssh myhost src
317 +'
318 +
319 test_expect_success NOT_MINGW,NOT_CYGWIN 'clone local path foo:bar' '
320 + clear_ssh &&
321 cp -R src "foo:bar" &&
285 - git clone "./foo:bar" foobar
322 + git clone "./foo:bar" foobar &&
323 + expect_ssh none
324 +'
325 +
326 +test_expect_success 'bracketed hostnames are still ssh' '
327 + clear_ssh &&
328 + git clone "[myhost:123]:src" ssh-bracket-clone &&
329 + expect_ssh myhost:123 src
330 '
331
332 test_done