Program: 91286
Project: 91286
Buggy source:
/** 
 * Write the prepared pack to the supplied stream. <p> At first, this method collects and sorts objects to pack, then deltas search is performed if set up accordingly, finally pack stream is written. </p> <p> All reused objects data checksum (Adler32/CRC32) is computed and validated against existing checksum. </p>
 * @param compressMonitor progress monitor to report object compression work.
 * @param writeMonitor progress monitor to report the number of objects written.
 * @param packStream output stream of pack data. The stream should be buffered by the caller. The caller is responsible for closing the stream.
 * @throws IOException an error occurred reading a local object's data to include in the pack, or writing compressed object data to the output stream.
 * @throws WriteAbortedException the write operation is aborted by {@link PackWriter.ObjectCountCallback}.
 */
public void writePack(ProgressMonitor compressMonitor,ProgressMonitor writeMonitor,OutputStream packStream) throws IOException {
  if (compressMonitor == null)   compressMonitor=NullProgressMonitor.INSTANCE;
  if (writeMonitor == null)   writeMonitor=NullProgressMonitor.INSTANCE;
  excludeInPacks=null;
  excludeInPackLast=null;
  boolean needSearchForReuse=reuseSupport != null && (reuseDeltas || config.isReuseObjects() || !cachedPacks.isEmpty());
  if (compressMonitor instanceof BatchingProgressMonitor) {
    long delay=1000;
    if (needSearchForReuse && config.isDeltaCompress())     delay=500;
    ((BatchingProgressMonitor)compressMonitor).setDelayStart(delay,TimeUnit.MILLISECONDS);
  }
  if (needSearchForReuse)   searchForReuse(compressMonitor);
  if (config.isDeltaCompress())   searchForDeltas(compressMonitor);
  crc32=new CRC32();
  final PackOutputStream out=new PackOutputStream(writeMonitor,isIndexDisabled() ? packStream : new CheckedOutputStream(packStream,crc32),this);
  long objCnt=getObjectCount();
  stats.totalObjects=objCnt;
  if (callback != null)   callback.setObjectCount(objCnt);
  beginPhase(PackingPhase.WRITING,writeMonitor,objCnt);
  long writeStart=System.currentTimeMillis();
  try {
    out.writeFileHeader(PACK_VERSION_GENERATED,objCnt);
    out.flush();
    writeObjects(out);
    if (!edgeObjects.isEmpty() || !cachedPacks.isEmpty()) {
      for (      Statistics.ObjectType typeStat : stats.objectTypes) {
        if (typeStat == null)         continue;
        stats.thinPackBytes+=typeStat.bytes;
      }
    }
    stats.reusedPacks=Collections.unmodifiableList(cachedPacks);
    for (    CachedPack pack : cachedPacks) {
      long deltaCnt=pack.getDeltaCount();
      stats.reusedObjects+=pack.getObjectCount();
      stats.reusedDeltas+=deltaCnt;
      stats.totalDeltas+=deltaCnt;
      reuseSupport.copyPackAsIs(out,pack);
    }
    writeChecksum(out);
    out.flush();
  }
  finally {
    stats.timeWriting=System.currentTimeMillis() - writeStart;
    stats.depth=depth;
    for (    Statistics.ObjectType typeStat : stats.objectTypes) {
      if (typeStat == null)       continue;
      typeStat.cntDeltas+=typeStat.reusedDeltas;
      stats.reusedObjects+=typeStat.reusedObjects;
      stats.reusedDeltas+=typeStat.reusedDeltas;
      stats.totalDeltas+=typeStat.cntDeltas;
    }
  }
  stats.totalBytes=out.length();
  reader.close();
  endPhase(writeMonitor);
}

Fixed version (ground truth):
/** 
 * Write the prepared pack to the supplied stream. <p> At first, this method collects and sorts objects to pack, then deltas search is performed if set up accordingly, finally pack stream is written. </p> <p> All reused objects data checksum (Adler32/CRC32) is computed and validated against existing checksum. </p>
 * @param compressMonitor progress monitor to report object compression work.
 * @param writeMonitor progress monitor to report the number of objects written.
 * @param packStream output stream of pack data. The stream should be buffered by the caller. The caller is responsible for closing the stream.
 * @throws IOException an error occurred reading a local object's data to include in the pack, or writing compressed object data to the output stream.
 * @throws WriteAbortedException the write operation is aborted by {@link ObjectCountCallback}.
 */
public void writePack(ProgressMonitor compressMonitor,ProgressMonitor writeMonitor,OutputStream packStream) throws IOException {
  if (compressMonitor == null)   compressMonitor=NullProgressMonitor.INSTANCE;
  if (writeMonitor == null)   writeMonitor=NullProgressMonitor.INSTANCE;
  excludeInPacks=null;
  excludeInPackLast=null;
  boolean needSearchForReuse=reuseSupport != null && (reuseDeltas || config.isReuseObjects() || !cachedPacks.isEmpty());
  if (compressMonitor instanceof BatchingProgressMonitor) {
    long delay=1000;
    if (needSearchForReuse && config.isDeltaCompress())     delay=500;
    ((BatchingProgressMonitor)compressMonitor).setDelayStart(delay,TimeUnit.MILLISECONDS);
  }
  if (needSearchForReuse)   searchForReuse(compressMonitor);
  if (config.isDeltaCompress())   searchForDeltas(compressMonitor);
  crc32=new CRC32();
  final PackOutputStream out=new PackOutputStream(writeMonitor,isIndexDisabled() ? packStream : new CheckedOutputStream(packStream,crc32),this);
  long objCnt=getObjectCount();
  stats.totalObjects=objCnt;
  if (callback != null)   callback.setObjectCount(objCnt);
  beginPhase(PackingPhase.WRITING,writeMonitor,objCnt);
  long writeStart=System.currentTimeMillis();
  try {
    out.writeFileHeader(PACK_VERSION_GENERATED,objCnt);
    out.flush();
    writeObjects(out);
    if (!edgeObjects.isEmpty() || !cachedPacks.isEmpty()) {
      for (      Statistics.ObjectType typeStat : stats.objectTypes) {
        if (typeStat == null)         continue;
        stats.thinPackBytes+=typeStat.bytes;
      }
    }
    stats.reusedPacks=Collections.unmodifiableList(cachedPacks);
    for (    CachedPack pack : cachedPacks) {
      long deltaCnt=pack.getDeltaCount();
      stats.reusedObjects+=pack.getObjectCount();
      stats.reusedDeltas+=deltaCnt;
      stats.totalDeltas+=deltaCnt;
      reuseSupport.copyPackAsIs(out,pack);
    }
    writeChecksum(out);
    out.flush();
  }
  finally {
    stats.timeWriting=System.currentTimeMillis() - writeStart;
    stats.depth=depth;
    for (    Statistics.ObjectType typeStat : stats.objectTypes) {
      if (typeStat == null)       continue;
      typeStat.cntDeltas+=typeStat.reusedDeltas;
      stats.reusedObjects+=typeStat.reusedObjects;
      stats.reusedDeltas+=typeStat.reusedDeltas;
      stats.totalDeltas+=typeStat.cntDeltas;
    }
  }
  stats.totalBytes=out.length();
  reader.close();
  endPhase(writeMonitor);
}