summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/IndexPackTest.java59
-rw-r--r--org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java8
2 files changed, 67 insertions, 0 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/IndexPackTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/IndexPackTest.java
index 78f4393c3a..e18f741ac4 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/IndexPackTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/transport/IndexPackTest.java
@@ -46,16 +46,25 @@
package org.eclipse.jgit.transport;
+import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
+import java.security.MessageDigest;
+import java.util.zip.Deflater;
+import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.Constants;
+import org.eclipse.jgit.lib.NullProgressMonitor;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PackFile;
import org.eclipse.jgit.lib.RepositoryTestCase;
import org.eclipse.jgit.lib.TextProgressMonitor;
+import org.eclipse.jgit.revwalk.RevBlob;
import org.eclipse.jgit.util.JGitTestUtil;
+import org.eclipse.jgit.util.NB;
+import org.eclipse.jgit.util.TemporaryBuffer;
/**
* Test indexing of git packs. A pack is read from a stream, copied
@@ -120,4 +129,54 @@ public class IndexPackTest extends RepositoryTestCase {
is.close();
}
}
+
+ public void testTinyThinPack() throws Exception {
+ TestRepository d = new TestRepository(db);
+ RevBlob a = d.blob("a");
+
+ TemporaryBuffer.Heap pack = new TemporaryBuffer.Heap(1024);
+
+ packHeader(pack, 1);
+
+ pack.write((Constants.OBJ_REF_DELTA) << 4 | 4);
+ a.copyRawTo(pack);
+ deflate(pack, new byte[] { 0x1, 0x1, 0x1, 'b' });
+
+ digest(pack);
+
+ final byte[] raw = pack.toByteArray();
+ IndexPack ip = IndexPack.create(db, new ByteArrayInputStream(raw));
+ ip.setFixThin(true);
+ ip.index(NullProgressMonitor.INSTANCE);
+ ip.renameAndOpenPack();
+ }
+
+ private void packHeader(TemporaryBuffer.Heap tinyPack, int cnt)
+ throws IOException {
+ final byte[] hdr = new byte[8];
+ NB.encodeInt32(hdr, 0, 2);
+ NB.encodeInt32(hdr, 4, cnt);
+
+ tinyPack.write(Constants.PACK_SIGNATURE);
+ tinyPack.write(hdr, 0, 8);
+ }
+
+ private void deflate(TemporaryBuffer.Heap tinyPack, final byte[] content)
+ throws IOException {
+ final Deflater deflater = new Deflater();
+ final byte[] buf = new byte[128];
+ deflater.setInput(content, 0, content.length);
+ deflater.finish();
+ do {
+ final int n = deflater.deflate(buf, 0, buf.length);
+ if (n > 0)
+ tinyPack.write(buf, 0, n);
+ } while (!deflater.finished());
+ }
+
+ private void digest(TemporaryBuffer.Heap buf) throws IOException {
+ MessageDigest md = Constants.newMessageDigest();
+ md.update(buf.toByteArray());
+ buf.write(md.digest());
+ }
}
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java b/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java
index 23faa42a24..29f200c52d 100644
--- a/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java
+++ b/org.eclipse.jgit/src/org/eclipse/jgit/transport/IndexPack.java
@@ -601,6 +601,14 @@ public class IndexPack {
throw new MissingObjectException(base, "delta base");
}
+ if (end - originalEOF < 20) {
+ // Ugly corner case; if what we appended on to complete deltas
+ // doesn't completely cover the SHA-1 we have to truncate off
+ // we need to shorten the file, otherwise we will include part
+ // of the old footer as object content.
+ packOut.setLength(end);
+ }
+
fixHeaderFooter(packcsum, packDigest.digest());
}