diff options
Diffstat (limited to 'org.eclipse.jgit')
4 files changed, 38 insertions, 15 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java index a8d6dda066..024bd15b03 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/ObjectDirectory.java @@ -292,7 +292,20 @@ public class ObjectDirectory extends ObjectDatabase { PackList o, n; do { o = packList.get(); + + // If the pack in question is already present in the list + // (picked up by a concurrent thread that did a scan?) we + // do not want to insert it a second time. + // final PackFile[] oldList = o.packs; + final String name = pf.getPackFile().getName(); + for (PackFile p : oldList) { + if (PackFile.SORT.compare(pf, p) < 0) + break; + if (name.equals(p.getPackFile().getName())) + return; + } + final PackFile[] newList = new PackFile[1 + oldList.length]; newList[0] = pf; System.arraycopy(oldList, 0, newList, 1, oldList.length); @@ -416,10 +429,11 @@ public class ObjectDirectory extends ObjectDatabase { // This should never occur. It should be impossible for us // to have two pack files with the same name, as all of them // came out of the same directory. If it does, we promised to - // close any PackFiles we did not reuse, so close the one we - // just evicted out of the reuse map. + // close any PackFiles we did not reuse, so close the second, + // readers are likely to be actively using the first. // - prior.close(); + forReuse.put(prior.getPackFile().getName(), prior); + p.close(); } } return forReuse; diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PackWriter.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PackWriter.java index b30e5f7c23..0c8210f646 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/PackWriter.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/PackWriter.java @@ -718,12 +718,11 @@ public class PackWriter { final PackedObjectLoader reuse = open(otp); if (reuse != null) { try { - if (otp.isDeltaRepresentation()) { - writeDeltaObjectReuse(otp, reuse); - } else { + if (otp.isDeltaRepresentation()) + writeDeltaObjectHeader(otp, reuse); + else writeObjectHeader(otp.getType(), reuse.getSize()); - reuse.copyRawData(out, buf, windowCursor); - } + reuse.copyRawData(out, buf, windowCursor); } finally { reuse.endCopyRawData(); } @@ -773,7 +772,7 @@ public class PackWriter { } while (!deflater.finished()); } - private void writeDeltaObjectReuse(final ObjectToPack otp, + private void writeDeltaObjectHeader(final ObjectToPack otp, final PackedObjectLoader reuse) throws IOException { if (deltaBaseAsOffset && otp.getDeltaBase() != null) { writeObjectHeader(Constants.OBJ_OFS_DELTA, reuse.getRawSize()); @@ -792,7 +791,6 @@ public class PackWriter { otp.getDeltaBaseId().copyRawTo(buf, 0); out.write(buf, 0, Constants.OBJECT_ID_LENGTH); } - reuse.copyRawData(out, buf, windowCursor); } private void writeObjectHeader(final int objectType, long dataLength) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/lib/UnpackedObjectLoader.java b/org.eclipse.jgit/src/org/eclipse/jgit/lib/UnpackedObjectLoader.java index 005df4b98d..96a1f80241 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/lib/UnpackedObjectLoader.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/lib/UnpackedObjectLoader.java @@ -114,8 +114,13 @@ public class UnpackedObjectLoader extends ObjectLoader { int avail = 0; while (!inflater.finished() && avail < hdr.length) try { - avail += inflater.inflate(hdr, avail, hdr.length - - avail); + int uncompressed = inflater.inflate(hdr, avail, + hdr.length - avail); + if (uncompressed == 0) { + throw new CorruptObjectException(id, + "bad stream, corrupt header"); + } + avail += uncompressed; } catch (DataFormatException dfe) { final CorruptObjectException coe; coe = new CorruptObjectException(id, "bad stream"); @@ -172,8 +177,14 @@ public class UnpackedObjectLoader extends ObjectLoader { private void decompress(final AnyObjectId id, final Inflater inf, int p) throws CorruptObjectException { try { - while (!inf.finished()) - p += inf.inflate(bytes, p, objectSize - p); + while (!inf.finished()) { + int uncompressed = inf.inflate(bytes, p, objectSize - p); + p += uncompressed; + if (uncompressed == 0 && !inf.finished()) { + throw new CorruptObjectException(id, + "bad stream, corrupt header"); + } + } } catch (DataFormatException dfe) { final CorruptObjectException coe; coe = new CorruptObjectException(id, "bad stream"); diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java index 541f2748e7..530200b0ca 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/revwalk/FooterLine.java @@ -90,7 +90,7 @@ public final class FooterLine { int bPtr = keyStart; if (keyEnd - bPtr != len) return false; - for (int kPtr = 0; bPtr < len;) { + for (int kPtr = 0; kPtr < len;) { byte b = buffer[bPtr++]; if ('A' <= b && b <= 'Z') b += 'a' - 'A'; |