Permit ObjectChecker to optionally accept leading '0' in trees

The leading '0' is a broken mode that although incorrect in the
Git canonical tree format was created by a couple of libraries
frequently used on a popular Git hosting site. Some projects have
these modes stuck in their ancient history and cannot easily
repair the damage without a full history rewrite. Optionally permit
ObjectChecker to ignore them.

Bug: 307291
Change-Id: Ib921dfd77ce757e89280d1c00328a88430daef35
This commit is contained in:
Shawn Pearce 2014-03-11 17:19:37 -07:00
parent efd91ef8a7
commit 2f1bd3618d
2 changed files with 28 additions and 1 deletions

View File

@ -1108,6 +1108,14 @@ public void testValidTreeSorting8() throws CorruptObjectException {
checker.checkTree(data);
}
@Test
public void testAcceptTreeModeWithZero() throws CorruptObjectException {
StringBuilder b = new StringBuilder();
entry(b, "040000 a");
checker.setAllowLeadingZeroFileMode(true);
checker.checkTree(Constants.encodeASCII(b.toString()));
}
@Test
public void testInvalidTreeModeStartsWithZero1() {
final StringBuilder b = new StringBuilder();

View File

@ -97,6 +97,25 @@ public class ObjectChecker {
private final MutableInteger ptrout = new MutableInteger();
private boolean allowZeroMode;
/**
* Enable accepting leading zero mode in tree entries.
* <p>
* Some broken Git libraries generated leading zeros in the mode part of
* tree entries. This is technically incorrect but gracefully allowed by
* git-core. JGit rejects such trees by default, but may need to accept
* them on broken histories.
*
* @param allow allow leading zero mode.
* @return {@code this}.
* @since 3.4
*/
public ObjectChecker setAllowLeadingZeroFileMode(boolean allow) {
allowZeroMode = allow;
return this;
}
/**
* Check an object for parsing errors.
*
@ -308,7 +327,7 @@ public void checkTree(final byte[] raw) throws CorruptObjectException {
break;
if (c < '0' || c > '7')
throw new CorruptObjectException("invalid mode character");
if (thisMode == 0 && c == '0')
if (thisMode == 0 && c == '0' && !allowZeroMode)
throw new CorruptObjectException("mode starts with '0'");
thisMode <<= 3;
thisMode += c - '0';