Program: 64166
Project: 64166
Buggy source:
/** 
 * Reads the central directory of the given archive and populates the internal tables with ZipEntry instances. <p>The ZipEntrys will know all data that can be obtained from the central directory alone, but not the data that requires the local file header or additional data to be read.</p>
 */
private void populateFromCentralDirectory() throws IOException {
  positionAtCentralDirectory();
  byte[] cfh=new byte[CFH_LEN];
  byte[] signatureBytes=new byte[WORD];
  archive.readFully(signatureBytes);
  long sig=ZipLong.getValue(signatureBytes);
  final long cfhSig=ZipLong.getValue(ZipOutputStream.CFH_SIG);
  if (sig != cfhSig && startsWithLocalFileHeader()) {
    throw new IOException("String_Node_Str" + "String_Node_Str");
  }
  while (sig == cfhSig) {
    archive.readFully(cfh);
    int off=0;
    ZipEntry ze=new ZipEntry();
    int versionMadeBy=ZipShort.getValue(cfh,off);
    off+=SHORT;
    ze.setPlatform((versionMadeBy >> BYTE_SHIFT) & NIBLET_MASK);
    off+=WORD;
    ze.setMethod(ZipShort.getValue(cfh,off));
    off+=SHORT;
    long time=dosToJavaTime(ZipLong.getValue(cfh,off));
    ze.setTime(time);
    off+=WORD;
    ze.setCrc(ZipLong.getValue(cfh,off));
    off+=WORD;
    ze.setCompressedSize(ZipLong.getValue(cfh,off));
    off+=WORD;
    ze.setSize(ZipLong.getValue(cfh,off));
    off+=WORD;
    int fileNameLen=ZipShort.getValue(cfh,off);
    off+=SHORT;
    int extraLen=ZipShort.getValue(cfh,off);
    off+=SHORT;
    int commentLen=ZipShort.getValue(cfh,off);
    off+=SHORT;
    off+=SHORT;
    ze.setInternalAttributes(ZipShort.getValue(cfh,off));
    off+=SHORT;
    ze.setExternalAttributes(ZipLong.getValue(cfh,off));
    off+=WORD;
    byte[] fileName=new byte[fileNameLen];
    archive.readFully(fileName);
    ze.setName(getString(fileName));
    OffsetEntry offset=new OffsetEntry();
    offset.headerOffset=ZipLong.getValue(cfh,off);
    entries.put(ze,offset);
    nameMap.put(ze.getName(),ze);
    archive.skipBytes(extraLen);
    byte[] comment=new byte[commentLen];
    archive.readFully(comment);
    ze.setComment(getString(comment));
    archive.readFully(signatureBytes);
    sig=ZipLong.getValue(signatureBytes);
  }
}

Fixed version (ground truth):
/** 
 * Reads the central directory of the given archive and populates the internal tables with ZipEntry instances. <p>The ZipEntrys will know all data that can be obtained from the central directory alone, but not the data that requires the local file header or additional data to be read.</p>
 */
private void populateFromCentralDirectory() throws IOException {
  positionAtCentralDirectory();
  byte[] cfh=new byte[CFH_LEN];
  byte[] signatureBytes=new byte[WORD];
  archive.readFully(signatureBytes);
  long sig=ZipLong.getValue(signatureBytes);
  final long cfhSig=ZipLong.getValue(ZipOutputStream.CFH_SIG);
  if (sig != cfhSig && startsWithLocalFileHeader()) {
    throw new IOException("String_Node_Str" + "String_Node_Str");
  }
  while (sig == cfhSig) {
    archive.readFully(cfh);
    int off=0;
    ZipEntry ze=new ZipEntry();
    int versionMadeBy=ZipShort.getValue(cfh,off);
    off+=SHORT;
    ze.setPlatform((versionMadeBy >> BYTE_SHIFT) & NIBLET_MASK);
    off+=WORD;
    ze.setMethod(ZipShort.getValue(cfh,off));
    off+=SHORT;
    long time=dosToJavaTime(ZipLong.getValue(cfh,off));
    ze.setTime(time);
    off+=WORD;
    ze.setCrc(ZipLong.getValue(cfh,off));
    off+=WORD;
    ze.setCompressedSize(ZipLong.getValue(cfh,off));
    off+=WORD;
    ze.setSize(ZipLong.getValue(cfh,off));
    off+=WORD;
    int fileNameLen=ZipShort.getValue(cfh,off);
    off+=SHORT;
    int extraLen=ZipShort.getValue(cfh,off);
    off+=SHORT;
    int commentLen=ZipShort.getValue(cfh,off);
    off+=SHORT;
    off+=SHORT;
    ze.setInternalAttributes(ZipShort.getValue(cfh,off));
    off+=SHORT;
    ze.setExternalAttributes(ZipLong.getValue(cfh,off));
    off+=WORD;
    byte[] fileName=new byte[fileNameLen];
    archive.readFully(fileName);
    ze.setName(getString(fileName));
    OffsetEntry offset=new OffsetEntry();
    offset.headerOffset=ZipLong.getValue(cfh,off);
    entries.put(ze,offset);
    nameMap.put(ze.getName(),ze);
    int lenToSkip=extraLen;
    while (lenToSkip > 0) {
      int skipped=archive.skipBytes(lenToSkip);
      if (skipped <= 0) {
        throw new RuntimeException("String_Node_Str" + "String_Node_Str");
      }
      lenToSkip-=skipped;
    }
    byte[] comment=new byte[commentLen];
    archive.readFully(comment);
    ze.setComment(getString(comment));
    archive.readFully(signatureBytes);
    sig=ZipLong.getValue(signatureBytes);
  }
}