Fix data corruption in DirCacheIterator when EmptyTreeIterator is used
commitbd3c3db9b640c810519d1304c3e2b86ac4391eaf
authorShawn O. Pearce <spearce@spearce.org>
Mon, 11 May 2009 17:52:28 +0000 (11 10:52 -0700)
committerRobin Rosenberg <robin.rosenberg@dewire.com>
Tue, 12 May 2009 19:52:50 +0000 (12 21:52 +0200)
tree11f902143d40ab30f5ce9cd306bad77e47abdffd
parentde9f4b6de78523ed6992919880013e9ce877e1d2
Fix data corruption in DirCacheIterator when EmptyTreeIterator is used

When a DirCacheIterator was wrapped in an EmptyTreeIterator (such
as during a parallel TreeWalk where the other trees contain a
path that does not appear in the DirCachIterator) we corrupted
the DirCacheEntry path buffers by overwriting part of file name
components with '/' to match the other tree iterators' path length.

This happened because DirCacheIterator violated the iterator
assumption that the path buffer is always mutable.  Instead of
creating a mutable path, DirCacheIterator reused the path buffer
from the DirCacheEntry or the DirCacheTree.  These reused byte
arrays aren't mutable.

By delegating the EmptyTreeIterator creation to each iterator type
we can permit DirCacheIterator to control how it builds the empty
tree for the caller, ensuring that it copies the path buffer before
writing the '/' suffix onto it.

When EmptyTreeIterator has to grow the path buffer to create a new
iterator around itself, we can't just blindly replace every parent
iterator buffer with the larger path buffer.  DirCacheIterators will
be using a different path buffer, and they want to retain their
old path buffer, not the new larger buffer.

Noticed-by: Mark Struberg <struberg@yahoo.de>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Robin Rosenberg <robin.rosenberg@dewire.com>
org.spearce.jgit/src/org/spearce/jgit/dircache/DirCacheIterator.java
org.spearce.jgit/src/org/spearce/jgit/treewalk/AbstractTreeIterator.java
org.spearce.jgit/src/org/spearce/jgit/treewalk/EmptyTreeIterator.java
org.spearce.jgit/src/org/spearce/jgit/treewalk/TreeWalk.java