Merge "Restore checkObjectCollisions flag"

This commit is contained in:
Shawn Pearce 2015-06-04 16:35:50 -04:00 committed by Gerrit Code Review @ Eclipse.org
commit 336092afa7
1 changed files with 50 additions and 11 deletions

View File

@ -135,6 +135,8 @@ public static enum Source {
private boolean allowThin;
private boolean checkObjectCollisions;
private boolean needBaseObjectIds;
private boolean checkEofAfterPackFooter;
@ -204,6 +206,7 @@ protected PackParser(final ObjectDatabase odb, final InputStream src) {
objectDigest = Constants.newMessageDigest();
tempObjectId = new MutableObjectId();
packDigest = Constants.newMessageDigest();
checkObjectCollisions = true;
}
/** @return true if a thin pack (missing base objects) is permitted. */
@ -224,6 +227,39 @@ public void setAllowThin(final boolean allow) {
allowThin = allow;
}
/**
* @return if true received objects are verified to prevent collisions.
* @since 4.1
*/
protected boolean isCheckObjectCollisions() {
return checkObjectCollisions;
}
/**
* Enable checking for collisions with existing objects.
* <p>
* By default PackParser looks for each received object in the repository.
* If the object already exists, the existing object is compared
* byte-for-byte with the newly received copy to ensure they are identical.
* The receive is aborted with an exception if any byte differs. This check
* is necessary to prevent an evil attacker from supplying a replacement
* object into this repository in the event that a discovery enabling SHA-1
* collisions is made.
* <p>
* This check may be very costly to perform, and some repositories may have
* other ways to segregate newly received object data. The check is enabled
* by default, but can be explicitly disabled if the implementation can
* provide the same guarantee, or is willing to accept the risks associated
* with bypassing the check.
*
* @param check
* true to enable collision checking (strongly encouraged).
* @since 4.1
*/
protected void setCheckObjectCollisions(boolean check) {
checkObjectCollisions = check;
}
/**
* Configure this index pack instance to keep track of new objects.
* <p>
@ -988,7 +1024,8 @@ private void whole(final long pos, final int type, final long sz)
}
inf.close();
tempObjectId.fromRaw(objectDigest.digest(), 0);
checkContentLater = readCurs.has(tempObjectId);
checkContentLater = isCheckObjectCollisions()
&& readCurs.has(tempObjectId);
data = null;
} else {
@ -1022,17 +1059,19 @@ private void verifySafeObject(final AnyObjectId id, final int type,
}
}
try {
final ObjectLoader ldr = readCurs.open(id, type);
final byte[] existingData = ldr.getCachedBytes(data.length);
if (!Arrays.equals(data, existingData)) {
throw new IOException(MessageFormat.format(
JGitText.get().collisionOn, id.name()));
if (isCheckObjectCollisions()) {
try {
final ObjectLoader ldr = readCurs.open(id, type);
final byte[] existingData = ldr.getCachedBytes(data.length);
if (!Arrays.equals(data, existingData)) {
throw new IOException(MessageFormat.format(
JGitText.get().collisionOn, id.name()));
}
} catch (MissingObjectException notLocal) {
// This is OK, we don't have a copy of the object locally
// but the API throws when we try to read it as usually its
// an error to read something that doesn't exist.
}
} catch (MissingObjectException notLocal) {
// This is OK, we don't have a copy of the object locally
// but the API throws when we try to read it as usually its
// an error to read something that doesn't exist.
}
}