diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java index 9bd30b883..1eb218c86 100644 --- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java +++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java @@ -502,6 +502,22 @@ public class URIishTest { assertEquals(u, new URIish(str)); } + @Test + public void testSshProtoHostWithEmptyPortAndPath() throws Exception { + final String str = "ssh://example.com:/path"; + URIish u = new URIish(str); + assertEquals("ssh", u.getScheme()); + assertTrue(u.isRemote()); + assertEquals("/path", u.getRawPath()); + assertEquals("/path", u.getPath()); + assertEquals("example.com", u.getHost()); + assertEquals(-1, u.getPort()); + assertEquals("ssh://example.com/path", u.toString()); + assertEquals("ssh://example.com/path", u.toASCIIString()); + assertEquals(u, new URIish(str)); + assertEquals(u, new URIish("ssh://example.com/path")); + } + @Test public void testSshProtoWithUserAndPort() throws Exception { final String str = "ssh://user@example.com:33/some/p ath"; @@ -972,13 +988,6 @@ public class URIishTest { assertEquals("b.txt", u.getHumanishName()); } - @Test - public void testMissingPort() throws URISyntaxException { - final String incorrectSshUrl = "ssh://some-host:/path/to/repository.git"; - URIish u = new URIish(incorrectSshUrl); - assertFalse(TransportGitSsh.PROTO_SSH.canHandle(u)); - } - @Test public void testALot() throws URISyntaxException { // user pass host port path diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java index a41e47ec8..a048fe30f 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java @@ -95,7 +95,7 @@ public class URIish implements Serializable { * Part of a pattern which matches the optional port part of URIs. Defines * one capturing group containing the port without the preceding colon. */ - private static final String OPT_PORT_P = "(?::(\\d+))?"; //$NON-NLS-1$ + private static final String OPT_PORT_P = "(?::(\\d*))?"; //$NON-NLS-1$ /** * Part of a pattern which matches the ~username part (e.g. /~root in @@ -224,11 +224,23 @@ public class URIish implements Serializable { scheme = matcher.group(1); user = unescape(matcher.group(2)); pass = unescape(matcher.group(3)); - host = unescape(matcher.group(4)); - if (matcher.group(5) != null) - port = Integer.parseInt(matcher.group(5)); - rawPath = cleanLeadingSlashes( - n2e(matcher.group(6)) + n2e(matcher.group(7)), scheme); + // empty ports are in general allowed, except for URLs like + // file://D:/path for which it is more desirable to parse with + // host=null and path=D:/path + String portString = matcher.group(5); + if ("file".equals(scheme) && "".equals(portString)) { //$NON-NLS-1$ //$NON-NLS-2$ + rawPath = cleanLeadingSlashes( + n2e(matcher.group(4)) + ":" + portString //$NON-NLS-1$ + + n2e(matcher.group(6)) + n2e(matcher.group(7)), + scheme); + } else { + host = unescape(matcher.group(4)); + if (portString != null && portString.length() > 0) { + port = Integer.parseInt(portString); + } + rawPath = cleanLeadingSlashes( + n2e(matcher.group(6)) + n2e(matcher.group(7)), scheme); + } path = unescape(rawPath); return; }