summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristian Halstrick <christian.halstrick@sap.com>2010-10-06 17:29:25 +0200
committerMatthias Sohn <matthias.sohn@sap.com>2010-10-08 11:12:09 +0200
commit2160c09dd4f678c5f2f8e730945be637210b39de (patch)
tree5039bc6414ff05a2d43b7673f7e6990b03607802
parent213609520351bc26beab887dd7f41f09b0b70d89 (diff)
downloadjgit-2160c09dd4f678c5f2f8e730945be637210b39de.tar.gz
jgit-2160c09dd4f678c5f2f8e730945be637210b39de.zip
Refactored URI parsing to detect wrong URIs
There where quite some bugs regarding wrong URI parsing. In order to solve them the parsing has to be refactored. We now have specialized regexps for 'scheme://host/...', scp URIs and local file names. Now we can detect problems while parsing 'git://host:/abc' which was previously not possible. Bug: 315571 Bug: 292897 Bug: 307017 Bug: 323571 Bug: 317388 Change-Id: If72576576ebb6b9d9dc8b7e51ddd87c9909e8b62 Signed-off-by: Christian Halstrick <christian.halstrick@sap.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/URIishTest.java6
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java104
2 files changed, 82 insertions, 28 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 88651b75e6..6a53810d07 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
@@ -447,4 +447,10 @@ public class URIishTest extends TestCase {
assertEquals("secret@pass", u.getPass());
assertEquals(u, new URIish(str));
}
+
+ public void testMissingPort() throws URISyntaxException {
+ final String incorrectSshUrl = "ssh://some-host:/path/to/repository.git";
+ URIish u = new URIish(incorrectSshUrl);
+ assertFalse(TransportGitSsh.canHandle(u));
+ }
}
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 3c044fe675..82f80c547e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/URIish.java
@@ -78,10 +78,10 @@ public class URIish implements Serializable {
private static final String OPT_USER_PWD_P = "(?:([^/:@]+)(?::([^/]+))?@)?";
/**
- * Part of a pattern which matches the optional host part of URIs. Defines
- * one capturing group containing the host name.
+ * Part of a pattern which matches the host part of URIs. Defines one
+ * capturing group containing the host name.
*/
- private static final String OPT_HOST_P = "(?:([^/]+?))?";
+ private static final String HOST_P = "([^/:]+)";
/**
* Part of a pattern which matches the optional port part of URIs. Defines
@@ -90,6 +90,12 @@ public class URIish implements Serializable {
private static final String OPT_PORT_P = "(?::(\\d+))?";
/**
+ * Part of a pattern which matches the ~username part (e.g. /~root in
+ * git://host.xyz/~root/a.git) of URIs. Defines no capturing group.
+ */
+ private static final String USER_HOME_P = "(?:/~(?:[^/]+))";
+
+ /**
* Part of a pattern which matches the optional drive letter in paths (e.g.
* D: in file:///D:/a.txt). Defines no capturing group.
*/
@@ -99,7 +105,14 @@ public class URIish implements Serializable {
* Part of a pattern which matches a relative path. Relative paths don't
* start with slash or drive letters. Defines no capturing group.
*/
- private static final String OPT_RELATIVE_PATH_P = "(?:\\.\\.)?";
+ private static final String RELATIVE_PATH_P = "(?:(?:[^/]+/)*[^/]+/?)";
+
+ /**
+ * Part of a pattern which matches a relative or absolute path. Defines no
+ * capturing group.
+ */
+ private static final String PATH_P = "(" + OPT_DRIVE_LETTER_P + "/?"
+ + RELATIVE_PATH_P + ")";
private static final long serialVersionUID = 1L;
@@ -108,24 +121,37 @@ public class URIish implements Serializable {
* <code>scheme "://" user_password? hostname? portnumber? path</code>
*/
private static final Pattern FULL_URI = Pattern.compile("^" //
- + "(?:" //
+ SCHEME_P //
+ + "(?:" // start a group containing hostname and all options only
+ // availabe when a hostname is there
+ OPT_USER_PWD_P //
- + OPT_HOST_P //
+ + HOST_P //
+ OPT_PORT_P //
- + ")?" //
- + "(" + OPT_DRIVE_LETTER_P + OPT_RELATIVE_PATH_P + "/.+" //
- + ")$"); // /anything
+ + "(" // open a catpuring group the the user-home-dir part
+ + (USER_HOME_P + "?") //
+ + "/)" //
+ + ")?" // close the optional group containing hostname
+ + "(.+)?" //
+ + "$");
+
+ /**
+ * A pattern matching the reference to a local file. This may be an absolute
+ * path (maybe even containing windows drive-letters) or a relative path.
+ */
+ private static final Pattern LOCAL_FILE = Pattern.compile("^" //
+ + "(/?" + PATH_P + ")" //
+ + "$");
/**
* A pattern matching SCP URI's of the form user@host:path/to/repo.git
*/
private static final Pattern SCP_URI = Pattern.compile("^" //
- + "(?:([^@]+?)@)?" //
- + "([^:]+?)" //
- + ":" //
- + "(.+)" //
- + "$"); //
+ + OPT_USER_PWD_P //
+ + HOST_P //
+ + ":(" //
+ + ("(?:" + USER_HOME_P + "/)?") //
+ + RELATIVE_PATH_P //
+ + ")$");
private String scheme;
@@ -155,27 +181,49 @@ public class URIish implements Serializable {
host = matcher.group(4);
if (matcher.group(5) != null)
port = Integer.parseInt(matcher.group(5));
- path = matcher.group(6);
- if (path.length() >= 3
- && path.charAt(0) == '/'
- && path.charAt(2) == ':'
- && (path.charAt(1) >= 'A' && path.charAt(1) <= 'Z'
- || path.charAt(1) >= 'a' && path.charAt(1) <= 'z'))
- path = path.substring(1);
- else if (scheme != null && path.length() >= 2
- && path.charAt(0) == '/' && path.charAt(1) == '~')
- path = path.substring(1);
+ path = cleanLeadingSlashes(
+ n2e(matcher.group(6)) + n2e(matcher.group(7)), scheme);
} else {
matcher = SCP_URI.matcher(s);
if (matcher.matches()) {
user = matcher.group(1);
- host = matcher.group(2);
- path = matcher.group(3);
- } else
- throw new URISyntaxException(s, JGitText.get().cannotParseGitURIish);
+ pass = matcher.group(2);
+ host = matcher.group(3);
+ path = matcher.group(4);
+ } else {
+ matcher = LOCAL_FILE.matcher(s);
+ if (matcher.matches()) {
+ path = matcher.group(1);
+ } else
+ throw new URISyntaxException(s,
+ JGitText.get().cannotParseGitURIish);
+ }
}
}
+ private String n2e(String s) {
+ if (s == null)
+ return "";
+ else
+ return s;
+ }
+
+ // takes care to cut of a leading slash if a windows drive letter or a
+ // user-home-dir specifications are
+ private String cleanLeadingSlashes(String p, String s) {
+ if (p.length() >= 3
+ && p.charAt(0) == '/'
+ && p.charAt(2) == ':'
+ && (p.charAt(1) >= 'A' && p.charAt(1) <= 'Z' || p.charAt(1) >= 'a'
+ && p.charAt(1) <= 'z'))
+ return p.substring(1);
+ else if (s != null && p.length() >= 2 && p.charAt(0) == '/'
+ && p.charAt(1) == '~')
+ return p.substring(1);
+ else
+ return p;
+ }
+
/**
* Construct a URIish from a standard URL.
*