package org.eclipse.jgit.lib;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
+import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import org.eclipse.jgit.api.Git;
+import org.eclipse.jgit.errors.AmbiguousObjectException;
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
+import org.eclipse.jgit.errors.RevisionSyntaxException;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.Test;
public void testDistance_past_root() throws IOException {
assertEquals("42e4e7c5e507e113ebbb7801b16b52cf867b7ce1",db.resolve("6462e7d8024396b14d7651e2ec11e2bbf07a05c4~1").name());
assertNull(db.resolve("6462e7d8024396b14d7651e2ec11e2bbf07a05c4~~"));
+ assertNull(db.resolve("6462e7d8024396b14d7651e2ec11e2bbf07a05c4^^"));
assertNull(db.resolve("6462e7d8024396b14d7651e2ec11e2bbf07a05c4~2"));
assertNull(db.resolve("6462e7d8024396b14d7651e2ec11e2bbf07a05c4~99"));
assertNull(db.resolve("42e4e7c5e507e113ebbb7801b16b52cf867b7ce1~~"));
+ assertNull(db.resolve("42e4e7c5e507e113ebbb7801b16b52cf867b7ce1^^"));
assertNull(db.resolve("42e4e7c5e507e113ebbb7801b16b52cf867b7ce1~2"));
assertNull(db.resolve("42e4e7c5e507e113ebbb7801b16b52cf867b7ce1~99"));
assertEquals("42e4e7c5e507e113ebbb7801b16b52cf867b7ce1",db.resolve("master~6").name());
assertEquals("refs/remotes/origin/main", db.simplify("@{upstream}"));
}
+ @Test
+ public void invalidNames() throws AmbiguousObjectException, IOException {
+ assertTrue(Repository.isValidRefName("x/a"));
+ assertTrue(Repository.isValidRefName("x/a.b"));
+ assertTrue(Repository.isValidRefName("x/a@b"));
+ assertTrue(Repository.isValidRefName("x/a@b{x}"));
+ assertTrue(Repository.isValidRefName("x/a/b"));
+ assertTrue(Repository.isValidRefName("x/a]b")); // odd, yes..
+ assertTrue(Repository.isValidRefName("x/\u00a0")); // unicode is fine,
+ // even hard space
+ assertFalse(Repository.isValidRefName("x/.a"));
+ assertFalse(Repository.isValidRefName("x/a."));
+ assertFalse(Repository.isValidRefName("x/a..b"));
+ assertFalse(Repository.isValidRefName("x//a"));
+ assertFalse(Repository.isValidRefName("x/a/"));
+ assertFalse(Repository.isValidRefName("x/a//b"));
+ assertFalse(Repository.isValidRefName("x/a[b"));
+ assertFalse(Repository.isValidRefName("x/a^b"));
+ assertFalse(Repository.isValidRefName("x/a*b"));
+ assertFalse(Repository.isValidRefName("x/a?b"));
+ assertFalse(Repository.isValidRefName("x/a~1"));
+ assertFalse(Repository.isValidRefName("x/a\\b"));
+ assertFalse(Repository.isValidRefName("x/a\u0000"));
+
+ assertUnparseable(".");
+ assertUnparseable("x@{3");
+ assertUnparseable("x[b");
+ assertUnparseable("x y");
+ assertUnparseable("x.");
+ assertUnparseable(".x");
+ assertUnparseable("a..b");
+ assertUnparseable("x\\b");
+ assertUnparseable("a~b");
+ assertUnparseable("a^b");
+ assertUnparseable("a\u0000");
+ }
+
+ private void assertUnparseable(String s) throws AmbiguousObjectException,
+ IOException {
+ try {
+ db.resolve(s);
+ fail("'" + s + "' should be unparseable");
+ } catch (RevisionSyntaxException e) {
+ // good
+ }
+ }
+
private static ObjectId id(String name) {
return ObjectId.fromString(name);
}
case '^':
if (rev == null) {
if (name == null)
- name = new String(revChars, done, i);
+ if (done == 0)
+ name = new String(revChars, done, i);
+ else {
+ done = i + 1;
+ break;
+ }
rev = parseSimple(rw, name);
name = null;
if (rev == null)
rev = commit.getParent(pnum - 1);
}
i = j - 1;
- done = i;
+ done = j;
break;
case '{':
int k;
} else
throw new IncorrectObjectTypeException(rev,
Constants.TYPE_COMMIT);
-
}
} else {
rev = rw.peel(rev);
throw new IncorrectObjectTypeException(rev,
Constants.TYPE_COMMIT);
}
+ done = i + 1;
break;
case '~':
if (rev == null) {
if (name == null)
- name = new String(revChars, done, i);
+ if (done == 0)
+ name = new String(revChars, done, i);
+ else {
+ done = i + 1;
+ break;
+ }
rev = parseSimple(rw, name);
name = null;
if (rev == null)
--dist;
}
i = l - 1;
+ done = l;
break;
case '@':
if (rev != null)
throw new RevisionSyntaxException(revstr);
+ if (i + 1 < revChars.length && revChars[i + 1] != '{')
+ continue;
int m;
String time = null;
for (m = i + 2; m < revChars.length; ++m) {
// Currently checked out branch, HEAD if
// detached
name = Constants.HEAD;
+ if (!Repository.isValidRefName("x/" + name))
+ throw new RevisionSyntaxException(revstr);
Ref ref = getRef(name);
name = null;
if (ref == null)
name = new String(revChars, done, i);
if (name.equals(""))
name = Constants.HEAD;
+ if (!Repository.isValidRefName("x/" + name))
+ throw new RevisionSyntaxException(revstr);
Ref ref = getRef(name);
name = null;
if (ref == null)
return rev.copy();
if (name != null)
return name;
+ if (rev == null && done == revstr.length())
+ return null;
name = revstr.substring(done);
+ if (!Repository.isValidRefName("x/" + name))
+ throw new RevisionSyntaxException(revstr);
if (getRef(name) != null)
return name;
return resolveSimple(name);
if (ObjectId.isId(revstr))
return ObjectId.fromString(revstr);
- Ref r = getRefDatabase().getRef(revstr);
- if (r != null)
- return r.getObjectId();
+ if (Repository.isValidRefName("x/" + revstr)) {
+ Ref r = getRefDatabase().getRef(revstr);
+ if (r != null)
+ return r.getObjectId();
+ }
if (AbbreviatedObjectId.isId(revstr))
return resolveAbbreviation(revstr);
case '/':
if (i == 0 || i == len - 1)
return false;
+ if (p == '/')
+ return false;
components++;
break;
case '{':
case '~': case '^': case ':':
case '?': case '[': case '*':
case '\\':
+ case '\u007F':
return false;
}
p = c;