Skip to main content
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce2010-12-22 22:11:18 +0000
committerShawn O. Pearce2010-12-22 22:11:22 +0000
commit6533994bc97609630fd2f20f4dd457a8f19901d1 (patch)
treef364807a0c6c76c886e41cc95171ee4669ce365c /org.eclipse.jgit.test
parentedeea800a6b482cc721ac11b8d767ca0392947f8 (diff)
downloadjgit-6533994bc97609630fd2f20f4dd457a8f19901d1.tar.gz
jgit-6533994bc97609630fd2f20f4dd457a8f19901d1.tar.xz
jgit-6533994bc97609630fd2f20f4dd457a8f19901d1.zip
Fix ArrayIndexOutOfBoundsException in DirCacheIterator
If the 'TREE' extension contains an invalid subtree that has been removed, DirCacheIterator still tried to access it due to an invalid childCnt field within the parent DirCacheTree object. This is easy for a user to do, they just need to move all files out of a subdirectory. For example, the input for the JUnit test case for this bug was built using the following C Git sequence: mkdir -p a/b touch a/b/c q git add a/b/c q git write-tree git mv a/b/c a/a After the last step, the subdirectory a/b is empty, as its only file was moved into the parent directory. Because of the earlier `git write-tree` operation, there is a 'TREE' extension present, but the a and a/b subdirectories have been marked invalid by the rename. When JGit tried to iterate over the a tree, it tried to correct childCnt to be zero as a/b no longer exists, but it failed to update childCnt. Change-Id: I7a0f78fc48a36b1a83252d354618f6807fca0426 Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Diffstat (limited to 'org.eclipse.jgit.test')
-rw-r--r--org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/dircache.testRemovedSubtreebin0 -> 196 bytes
-rw-r--r--org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java25
2 files changed, 25 insertions, 0 deletions
diff --git a/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/dircache.testRemovedSubtree b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/dircache.testRemovedSubtree
new file mode 100644
index 0000000000..01aa24d110
--- /dev/null
+++ b/org.eclipse.jgit.test/tst-rsrc/org/eclipse/jgit/test/resources/dircache.testRemovedSubtree
Binary files differ
diff --git a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java
index 99acd528c9..bc84753f9b 100644
--- a/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java
+++ b/org.eclipse.jgit.test/tst/org/eclipse/jgit/dircache/DirCacheIteratorTest.java
@@ -43,12 +43,15 @@
package org.eclipse.jgit.dircache;
+import java.io.File;
import java.util.Collections;
import org.eclipse.jgit.lib.FileMode;
import org.eclipse.jgit.lib.RepositoryTestCase;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.PathFilterGroup;
+import org.eclipse.jgit.util.FS;
+import org.eclipse.jgit.util.JGitTestUtil;
public class DirCacheIteratorTest extends RepositoryTestCase {
public void testEmptyTree_NoTreeWalk() throws Exception {
@@ -269,4 +272,26 @@ public class DirCacheIteratorTest extends RepositoryTestCase {
assertFalse(tw.next());
}
}
+
+ public void testRemovedSubtree() throws Exception {
+ final File path = JGitTestUtil
+ .getTestResourceFile("dircache.testRemovedSubtree");
+
+ final DirCache dc = DirCache.read(path, FS.DETECTED);
+ assertEquals(2, dc.getEntryCount());
+
+ final TreeWalk tw = new TreeWalk(db);
+ tw.setRecursive(true);
+ tw.addTree(new DirCacheIterator(dc));
+
+ assertTrue(tw.next());
+ assertEquals("a/a", tw.getPathString());
+ assertSame(FileMode.REGULAR_FILE, tw.getFileMode(0));
+
+ assertTrue(tw.next());
+ assertEquals("q", tw.getPathString());
+ assertSame(FileMode.REGULAR_FILE, tw.getFileMode(0));
+
+ assertFalse(tw.next());
+ }
}

Back to the top