From 8cc783ca7d3180ec8b548dd67743f5fc1e9a6a15 Mon Sep 17 00:00:00 2001 From: Marc Strapetz Date: Sat, 9 Dec 2017 13:23:28 +0100 Subject: [PATCH] URIish: support for empty ports Properly parse URLs like "ssh://host:/path" Bug: 519187 Change-Id: I0054868e30509e4ba919444be16c2a20f741545a Signed-off-by: Marc Strapetz --- .../eclipse/jgit/transport/URIishTest.java | 23 ++++++++++++------ .../org/eclipse/jgit/transport/URIish.java | 24 ++++++++++++++----- 2 files changed, 34 insertions(+), 13 deletions(-) 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 void testSshProtoHostWithPort() throws Exception { 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 void testFileProtocol() throws IllegalArgumentException, 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 URIish(String s) throws URISyntaxException { 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; }