aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHan-Wen Nienhuys <hanwen@google.com>2017-05-22 14:48:39 +0200
committerMatthias Sohn <matthias.sohn@sap.com>2017-05-24 23:43:59 +0200
commit832808bd509c88f08848f3b0a75cbb4de7f55df6 (patch)
tree1dae8530acd0fa19f1ac0129b653ab39b6f867cb
parent2204cc986649265fd2748557f05f4521f177fa98 (diff)
downloadjgit-832808bd509c88f08848f3b0a75cbb4de7f55df6.tar.gz
jgit-832808bd509c88f08848f3b0a75cbb4de7f55df6.zip
Fix out-of-bounds exception in RepoCommand#relative
Change-Id: I9c91aa2ff037bff27a8131fba54be22f5f27d80d Signed-off-by: Han-Wen Nienhuys <hanwen@google.com> Signed-off-by: Matthias Sohn <matthias.sohn@sap.com>
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java1
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java31
2 files changed, 22 insertions, 10 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
index 24b5ad7dab..6ed2c215e9 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/gitrepo/RepoCommandTest.java
@@ -1120,6 +1120,7 @@ public class RepoCommandTest extends RepositoryTestCase {
testRelative("a/", "a/b", "b");
testRelative("/a/b/c", "/b/c", "../../b/c");
testRelative("/abc", "bcd", "bcd");
+ testRelative("abc", "def", "def");
testRelative("abc", "/bcd", "/bcd");
testRelative("http://a", "a/b", "a/b");
testRelative("http://base.com/a/", "http://child.com/a/b", "http://child.com/a/b");
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
index 6669c9cfb7..1de8a0be2e 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/gitrepo/RepoCommand.java
@@ -731,7 +731,9 @@ public class RepoCommand extends GitCommand<RevCommit> {
* Returns the child if either base or child is not a bare path. This provides a missing feature in
* java.net.URI (see http://bugs.java.com/view_bug.do?bug_id=6226081).
*/
+ private static final String SLASH = "/"; //$NON-NLS-1$
static URI relativize(URI current, URI target) {
+
// We only handle bare paths for now.
if (!target.toString().equals(target.getPath())) {
return target;
@@ -744,37 +746,46 @@ public class RepoCommand extends GitCommand<RevCommit> {
String dest = target.normalize().getPath();
// TODO(hanwen): maybe (absolute, relative) should throw an exception.
- if (cur.startsWith("/") != dest.startsWith("/")) { //$NON-NLS-1$//$NON-NLS-2$
+ if (cur.startsWith(SLASH) != dest.startsWith(SLASH)) {
return target;
}
- while (cur.startsWith("/")) { //$NON-NLS-1$
+ while (cur.startsWith(SLASH)) {
cur = cur.substring(1);
}
- while (dest.startsWith("/")) { //$NON-NLS-1$
+ while (dest.startsWith(SLASH)) {
dest = dest.substring(1);
}
- if (!cur.endsWith("/")) { //$NON-NLS-1$
+ if (cur.indexOf('/') == -1 || dest.indexOf('/') == -1) {
+ // Avoid having to special-casing in the next two ifs.
+ String prefix = "prefix/"; //$NON-NLS-1$
+ cur = prefix + cur;
+ dest = prefix + dest;
+ }
+
+ if (!cur.endsWith(SLASH)) {
// The current file doesn't matter.
- cur = cur.substring(0, cur.lastIndexOf('/'));
+ int lastSlash = cur.lastIndexOf('/');
+ cur = cur.substring(0, lastSlash);
}
String destFile = ""; //$NON-NLS-1$
- if (!dest.endsWith("/")) { //$NON-NLS-1$
+ if (!dest.endsWith(SLASH)) {
// We always have to provide the destination file.
- destFile = dest.substring(dest.lastIndexOf('/') + 1, dest.length());
+ int lastSlash = dest.lastIndexOf('/');
+ destFile = dest.substring(lastSlash + 1, dest.length());
dest = dest.substring(0, dest.lastIndexOf('/'));
}
- String[] cs = cur.split("/"); //$NON-NLS-1$
- String[] ds = dest.split("/"); //$NON-NLS-1$
+ String[] cs = cur.split(SLASH);
+ String[] ds = dest.split(SLASH);
int common = 0;
while (common < cs.length && common < ds.length && cs[common].equals(ds[common])) {
common++;
}
- StringJoiner j = new StringJoiner("/"); //$NON-NLS-1$
+ StringJoiner j = new StringJoiner(SLASH);
for (int i = common; i < cs.length; i++) {
j.add(".."); //$NON-NLS-1$
}