Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java')
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java141
1 files changed, 141 insertions, 0 deletions
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java
index d8b8750ba3..3272d598bc 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/merge/ResolveMergerTest.java
@@ -65,8 +65,12 @@ import org.eclipse.jgit.errors.NoMergeBaseException;
import org.eclipse.jgit.errors.NoMergeBaseException.MergeBaseFailureReason;
import org.eclipse.jgit.junit.RepositoryTestCase;
import org.eclipse.jgit.junit.TestRepository;
+import org.eclipse.jgit.lib.AnyObjectId;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
+import org.eclipse.jgit.lib.ObjectLoader;
+import org.eclipse.jgit.lib.ObjectReader;
+import org.eclipse.jgit.lib.ObjectStream;
import org.eclipse.jgit.merge.ResolveMerger.MergeFailureReason;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevObject;
@@ -689,6 +693,143 @@ public class ResolveMergerTest extends RepositoryTestCase {
}
}
+
+ /**
+ * Merging a change involving large binary files should short-circuit reads.
+ *
+ * @param strategy
+ * @throws Exception
+ */
+ @Theory
+ public void checkContentMergeLargeBinaries(MergeStrategy strategy) throws Exception {
+ Git git = Git.wrap(db);
+ final int LINELEN = 72;
+
+ // setup a merge that would work correctly if we disconsider the stray '\0'
+ // that the file contains near the start.
+ byte[] binary = new byte[LINELEN * 2000];
+ for (int i = 0; i < binary.length; i++) {
+ binary[i] = (byte)((i % LINELEN) == 0 ? '\n' : 'x');
+ }
+ binary[50] = '\0';
+
+ writeTrashFile("file", new String(binary, UTF_8));
+ git.add().addFilepattern("file").call();
+ RevCommit first = git.commit().setMessage("added file").call();
+
+ // Generate an edit in a single line.
+ int idx = LINELEN * 1200 + 1;
+ byte save = binary[idx];
+ binary[idx] = '@';
+ writeTrashFile("file", new String(binary, UTF_8));
+
+ binary[idx] = save;
+ git.add().addFilepattern("file").call();
+ RevCommit masterCommit = git.commit().setAll(true)
+ .setMessage("modified file l 1200").call();
+
+ git.checkout().setCreateBranch(true).setStartPoint(first).setName("side").call();
+ binary[LINELEN * 1500 + 1] = '!';
+ writeTrashFile("file", new String(binary, UTF_8));
+ git.add().addFilepattern("file").call();
+ RevCommit sideCommit = git.commit().setAll(true)
+ .setMessage("modified file l 1500").call();
+
+ try (ObjectInserter ins = db.newObjectInserter()) {
+ // Check that we don't read the large blobs.
+ ObjectInserter forbidInserter = new ObjectInserter.Filter() {
+ @Override
+ protected ObjectInserter delegate() {
+ return ins;
+ }
+
+ @Override
+ public ObjectReader newReader() {
+ return new BigReadForbiddenReader(super.newReader(), 8000);
+ }
+ };
+
+ ResolveMerger merger =
+ (ResolveMerger) strategy.newMerger(forbidInserter, db.getConfig());
+ boolean noProblems = merger.merge(masterCommit, sideCommit);
+ assertFalse(noProblems);
+ }
+ }
+
+ /**
+ * Throws an exception if reading beyond limit.
+ */
+ class BigReadForbiddenStream extends ObjectStream.Filter {
+ int limit;
+
+ BigReadForbiddenStream(ObjectStream orig, int limit) {
+ super(orig.getType(), orig.getSize(), orig);
+ this.limit = limit;
+ }
+
+ @Override
+ public long skip(long n) throws IOException {
+ limit -= n;
+ if (limit < 0) {
+ throw new IllegalStateException();
+ }
+
+ return super.skip(n);
+ }
+
+ @Override
+ public int read() throws IOException {
+ int r = super.read();
+ limit--;
+ if (limit < 0) {
+ throw new IllegalStateException();
+ }
+ return r;
+ }
+
+ @Override
+ public int read(byte[] b, int off, int len) throws IOException {
+ int n = super.read(b, off, len);
+ limit -= n;
+ if (limit < 0) {
+ throw new IllegalStateException();
+ }
+ return n;
+ }
+ }
+
+ class BigReadForbiddenReader extends ObjectReader.Filter {
+ ObjectReader delegate;
+ int limit;
+
+ @Override
+ protected ObjectReader delegate() {
+ return delegate;
+ }
+
+ BigReadForbiddenReader(ObjectReader delegate, int limit) {
+ this.delegate = delegate;
+ this.limit = limit;
+ }
+
+ @Override
+ public ObjectLoader open(AnyObjectId objectId, int typeHint) throws IOException {
+ ObjectLoader orig = super.open(objectId, typeHint);
+ return new ObjectLoader.Filter() {
+ @Override
+ protected ObjectLoader delegate() {
+ return orig;
+ }
+
+ @Override
+ public ObjectStream openStream() throws IOException {
+ ObjectStream os = orig.openStream();
+ return new BigReadForbiddenStream(os, limit);
+ }
+ };
+ }
+ }
+
@Theory
public void checkContentMergeConflict(MergeStrategy strategy)
throws Exception {

Back to the top