Filter corrupt objects from DfsReader.selectObjectRepresentation()

PackWriter.writeObject() can get into an infinite loop when corrupt
packs are present. When it finds a pack file with an object that can be
reused it calls DfsPackFile.copyAsIs(). If that method sees an invalid
CRC, it adds the object to the DfsPackFile's corrupt object list and
throws a CorruptObjectException, which it later catches as an
IOException and wraps in a
StoredObjectRepresentationNotAvailableException.
PackWriter.writeObjectImpl() catches that SORNAE and retries the
operation by calling DfsReader.selectObjectRepresentation(). But
currently that method returns the same object which was just seen to
be corrupt.

Change DfsPackFile.isCorrupt() from private to package private, and use
that method in DfsReader.selectObjectRepresentation() to filter out
corrupt objects.

The stack traces that show the problem are:
  org.eclipse.jgit.errors.CorruptObjectException.<init>(CorruptObjectException.java:113)
  org.eclipse.jgit.internal.storage.dfs.DfsPackFile.copyAsIs(DfsPackFile.java:624)
  org.eclipse.jgit.internal.storage.dfs.DfsReader.copyObjectAsIs(DfsReader.java:491)
  org.eclipse.jgit.internal.storage.pack.PackWriter.writeObjectImpl(PackWriter.java:1478)
  org.eclipse.jgit.internal.storage.pack.PackWriter.writeObject(PackWriter.java:1455)

  org.eclipse.jgit.internal.storage.dfs.DfsPackFile.getPackIndex(DfsPackFile.java:228)
  org.eclipse.jgit.internal.storage.dfs.DfsReader.findAllFromPack(DfsReader.java:476)
  org.eclipse.jgit.internal.storage.dfs.DfsReader.selectObjectRepresentation(DfsReader.java:455)
  org.eclipse.jgit.internal.storage.pack.PackWriter.writeObjectImpl(PackWriter.java:1492)
  org.eclipse.jgit.internal.storage.pack.PackWriter.writeObject(PackWriter.java:1455)

Change-Id: Iad7bbcaed1f11a6aa3b4f5af911a73a34c0fabfd
Signed-off-by: Terry Parker <tparker@google.com>
This commit is contained in:
Terry Parker 2016-04-07 16:24:10 -07:00
parent 7d2b3b9e25
commit 2708b11b6c
2 changed files with 2 additions and 2 deletions

View File

@ -1189,7 +1189,7 @@ void representation(DfsObjectRepresentation r, final long pos,
}
}
private boolean isCorrupt(long offset) {
boolean isCorrupt(long offset) {
LongList list = corruptObjects;
if (list == null)
return false;

View File

@ -476,7 +476,7 @@ private List<DfsObjectToPack> findAllFromPack(DfsPackFile pack,
PackIndex idx = pack.getPackIndex(this);
for (ObjectToPack otp : objects) {
long p = idx.findOffset(otp);
if (0 < p) {
if (0 < p && !pack.isCorrupt(p)) {
otp.setOffset(p);
tmp.add((DfsObjectToPack) otp);
}