/**
  * If the entry needs Zip64 extra information inside the central directory then configure its
  * data.
  */
 private void handleZip64Extra(ZipArchiveEntry ze, long lfhOffset, boolean needsZip64Extra) {
   if (needsZip64Extra) {
     Zip64ExtendedInformationExtraField z64 = getZip64Extra(ze);
     if (ze.getCompressedSize() >= ZIP64_MAGIC || ze.getSize() >= ZIP64_MAGIC) {
       z64.setCompressedSize(new ZipEightByteInteger(ze.getCompressedSize()));
       z64.setSize(new ZipEightByteInteger(ze.getSize()));
     } else {
       // reset value that may have been set for LFH
       z64.setCompressedSize(null);
       z64.setSize(null);
     }
     if (lfhOffset >= ZIP64_MAGIC) {
       z64.setRelativeHeaderOffset(new ZipEightByteInteger(lfhOffset));
     }
     ze.setExtra();
   }
 }
 /**
  * Writes the data descriptor entry.
  *
  * @param ze the entry to write
  * @throws IOException on error
  */
 protected void writeDataDescriptor(ZipArchiveEntry ze) throws IOException {
   if (ze.getMethod() != DEFLATED || raf != null) {
     return;
   }
   writeOut(DD_SIG);
   writeOut(ZipLong.getBytes(ze.getCrc()));
   int sizeFieldSize = WORD;
   if (!hasZip64Extra(ze)) {
     writeOut(ZipLong.getBytes(ze.getCompressedSize()));
     writeOut(ZipLong.getBytes(ze.getSize()));
   } else {
     sizeFieldSize = DWORD;
     writeOut(ZipEightByteInteger.getBytes(ze.getCompressedSize()));
     writeOut(ZipEightByteInteger.getBytes(ze.getSize()));
   }
   written += 2 * WORD + 2 * sizeFieldSize;
 }
 /**
  * If the mode is AsNeeded and the entry is a compressed entry of unknown size that gets written
  * to a non-seekable stream the change the default to Never.
  *
  * @since 1.3
  */
 private Zip64Mode getEffectiveZip64Mode(ZipArchiveEntry ze) {
   if (zip64Mode != Zip64Mode.AsNeeded
       || raf != null
       || ze.getMethod() != DEFLATED
       || ze.getSize() != ArchiveEntry.SIZE_UNKNOWN) {
     return zip64Mode;
   }
   return Zip64Mode.Never;
 }
  /**
   * Test case for <a href="https://issues.apache.org/jira/browse/COMPRESS-264" >COMPRESS-264</a>.
   */
  @Test
  public void testReadingOfFirstStoredEntry() throws Exception {
    ZipArchiveInputStream in =
        new ZipArchiveInputStream(new FileInputStream(getFile("COMPRESS-264.zip")));

    try {
      ZipArchiveEntry ze = in.getNextZipEntry();
      assertEquals(5, ze.getSize());
      assertArrayEquals(new byte[] {'d', 'a', 't', 'a', '\n'}, IOUtils.toByteArray(in));
    } finally {
      in.close();
    }
  }
  @Test
  public void testUnzipBZip2CompressedEntry() throws Exception {
    ZipArchiveInputStream in =
        new ZipArchiveInputStream(new FileInputStream(getFile("bzip2-zip.zip")));

    try {
      ZipArchiveEntry ze = in.getNextZipEntry();
      assertEquals(42, ze.getSize());
      byte[] expected = new byte[42];
      Arrays.fill(expected, (byte) 'a');
      assertArrayEquals(expected, IOUtils.toByteArray(in));
    } finally {
      in.close();
    }
  }
 /* (non-Javadoc)
  * @see java.lang.Object#equals(java.lang.Object)
  */
 @Override
 public boolean equals(Object obj) {
   if (this == obj) {
     return true;
   }
   if (obj == null || getClass() != obj.getClass()) {
     return false;
   }
   ZipArchiveEntry other = (ZipArchiveEntry) obj;
   String myName = getName();
   String otherName = other.getName();
   if (myName == null) {
     if (otherName != null) {
       return false;
     }
   } else if (!myName.equals(otherName)) {
     return false;
   }
   String myComment = getComment();
   String otherComment = other.getComment();
   if (myComment == null) {
     myComment = "";
   }
   if (otherComment == null) {
     otherComment = "";
   }
   return getTime() == other.getTime()
       && myComment.equals(otherComment)
       && getInternalAttributes() == other.getInternalAttributes()
       && getPlatform() == other.getPlatform()
       && getExternalAttributes() == other.getExternalAttributes()
       && getMethod() == other.getMethod()
       && getSize() == other.getSize()
       && getCrc() == other.getCrc()
       && getCompressedSize() == other.getCompressedSize()
       && Arrays.equals(getCentralDirectoryExtra(), other.getCentralDirectoryExtra())
       && Arrays.equals(getLocalFileDataExtra(), other.getLocalFileDataExtra())
       && gpb.equals(other.gpb);
 }
  /**
   * Writes the central file header entry.
   *
   * @param ze the entry to write
   * @throws IOException on error
   * @throws Zip64RequiredException if the archive's size exceeds 4 GByte and {@link Zip64Mode
   *     #setUseZip64} is {@link Zip64Mode#Never}.
   */
  protected void writeCentralFileHeader(ZipArchiveEntry ze) throws IOException {
    writeOut(CFH_SIG);
    written += WORD;

    final long lfhOffset = offsets.get(ze).longValue();
    final boolean needsZip64Extra =
        hasZip64Extra(ze)
            || ze.getCompressedSize() >= ZIP64_MAGIC
            || ze.getSize() >= ZIP64_MAGIC
            || lfhOffset >= ZIP64_MAGIC;

    if (needsZip64Extra && zip64Mode == Zip64Mode.Never) {
      // must be the offset that is too big, otherwise an
      // exception would have been throw in putArchiveEntry or
      // closeArchiveEntry
      throw new Zip64RequiredException(Zip64RequiredException.ARCHIVE_TOO_BIG_MESSAGE);
    }

    handleZip64Extra(ze, lfhOffset, needsZip64Extra);

    // version made by
    // CheckStyle:MagicNumber OFF
    writeOut(
        ZipShort.getBytes(
            (ze.getPlatform() << 8)
                | (!hasUsedZip64 ? DATA_DESCRIPTOR_MIN_VERSION : ZIP64_MIN_VERSION)));
    written += SHORT;

    final int zipMethod = ze.getMethod();
    final boolean encodable = zipEncoding.canEncode(ze.getName());
    writeVersionNeededToExtractAndGeneralPurposeBits(
        zipMethod, !encodable && fallbackToUTF8, needsZip64Extra);
    written += WORD;

    // compression method
    writeOut(ZipShort.getBytes(zipMethod));
    written += SHORT;

    // last mod. time and date
    writeOut(ZipUtil.toDosTime(ze.getTime()));
    written += WORD;

    // CRC
    // compressed length
    // uncompressed length
    writeOut(ZipLong.getBytes(ze.getCrc()));
    if (ze.getCompressedSize() >= ZIP64_MAGIC || ze.getSize() >= ZIP64_MAGIC) {
      writeOut(ZipLong.ZIP64_MAGIC.getBytes());
      writeOut(ZipLong.ZIP64_MAGIC.getBytes());
    } else {
      writeOut(ZipLong.getBytes(ze.getCompressedSize()));
      writeOut(ZipLong.getBytes(ze.getSize()));
    }
    // CheckStyle:MagicNumber OFF
    written += 12;
    // CheckStyle:MagicNumber ON

    ByteBuffer name = getName(ze);

    writeOut(ZipShort.getBytes(name.limit()));
    written += SHORT;

    // extra field length
    byte[] extra = ze.getCentralDirectoryExtra();
    writeOut(ZipShort.getBytes(extra.length));
    written += SHORT;

    // file comment length
    String comm = ze.getComment();
    if (comm == null) {
      comm = "";
    }

    ByteBuffer commentB = getEntryEncoding(ze).encode(comm);

    writeOut(ZipShort.getBytes(commentB.limit()));
    written += SHORT;

    // disk number start
    writeOut(ZERO);
    written += SHORT;

    // internal file attributes
    writeOut(ZipShort.getBytes(ze.getInternalAttributes()));
    written += SHORT;

    // external file attributes
    writeOut(ZipLong.getBytes(ze.getExternalAttributes()));
    written += WORD;

    // relative offset of LFH
    writeOut(ZipLong.getBytes(Math.min(lfhOffset, ZIP64_MAGIC)));
    written += WORD;

    // file name
    writeOut(name.array(), name.arrayOffset(), name.limit() - name.position());
    written += name.limit();

    // extra field
    writeOut(extra);
    written += extra.length;

    // file comment
    writeOut(commentB.array(), commentB.arrayOffset(), commentB.limit() - commentB.position());
    written += commentB.limit();
  }
  /**
   * Writes the local file header entry
   *
   * @param ze the entry to write
   * @throws IOException on error
   */
  protected void writeLocalFileHeader(ZipArchiveEntry ze) throws IOException {

    boolean encodable = zipEncoding.canEncode(ze.getName());
    ByteBuffer name = getName(ze);

    if (createUnicodeExtraFields != UnicodeExtraFieldPolicy.NEVER) {
      addUnicodeExtraFields(ze, encodable, name);
    }

    offsets.put(ze, Long.valueOf(written));

    writeOut(LFH_SIG);
    written += WORD;

    // store method in local variable to prevent multiple method calls
    final int zipMethod = ze.getMethod();

    writeVersionNeededToExtractAndGeneralPurposeBits(
        zipMethod, !encodable && fallbackToUTF8, hasZip64Extra(ze));
    written += WORD;

    // compression method
    writeOut(ZipShort.getBytes(zipMethod));
    written += SHORT;

    // last mod. time and date
    writeOut(ZipUtil.toDosTime(ze.getTime()));
    written += WORD;

    // CRC
    // compressed length
    // uncompressed length
    entry.localDataStart = written;
    if (zipMethod == DEFLATED || raf != null) {
      writeOut(LZERO);
      if (hasZip64Extra(entry.entry)) {
        // point to ZIP64 extended information extra field for
        // sizes, may get rewritten once sizes are known if
        // stream is seekable
        writeOut(ZipLong.ZIP64_MAGIC.getBytes());
        writeOut(ZipLong.ZIP64_MAGIC.getBytes());
      } else {
        writeOut(LZERO);
        writeOut(LZERO);
      }
    } else {
      writeOut(ZipLong.getBytes(ze.getCrc()));
      byte[] size = ZipLong.ZIP64_MAGIC.getBytes();
      if (!hasZip64Extra(ze)) {
        size = ZipLong.getBytes(ze.getSize());
      }
      writeOut(size);
      writeOut(size);
    }
    // CheckStyle:MagicNumber OFF
    written += 12;
    // CheckStyle:MagicNumber ON

    // file name length
    writeOut(ZipShort.getBytes(name.limit()));
    written += SHORT;

    // extra field length
    byte[] extra = ze.getLocalFileDataExtra();
    writeOut(ZipShort.getBytes(extra.length));
    written += SHORT;

    // file name
    writeOut(name.array(), name.arrayOffset(), name.limit() - name.position());
    written += name.limit();

    // extra field
    writeOut(extra);
    written += extra.length;

    entry.dataStart = written;
  }
 /**
  * Whether to addd a Zip64 extended information extra field to the local file header.
  *
  * <p>Returns true if
  *
  * <ul>
  *   <li>mode is Always
  *   <li>or we already know it is going to be needed
  *   <li>or the size is unknown and we can ensure it won't hurt other implementations if we add it
  *       (i.e. we can erase its usage
  * </ul>
  */
 private boolean shouldAddZip64Extra(ZipArchiveEntry entry, Zip64Mode mode) {
   return mode == Zip64Mode.Always
       || entry.getSize() >= ZIP64_MAGIC
       || entry.getCompressedSize() >= ZIP64_MAGIC
       || (entry.getSize() == ArchiveEntry.SIZE_UNKNOWN && raf != null && mode != Zip64Mode.Never);
 }
Exemple #10
0
  private cfQueryResultData performZiplist(cfSession session, File zipfile, String charset)
      throws IOException {
    ZipFile zFile = null;
    try {
      cfQueryResultData filesQuery =
          new cfQueryResultData(
              new String[] {
                "name",
                "type",
                "compressedsize",
                "size",
                "compressedpercent",
                "datelastmodified",
                "comment"
              },
              "CFZIP");
      zFile = new ZipFile(zipfile, charset);

      List<Map<String, cfData>> allResultRows = new ArrayList<Map<String, cfData>>();
      Map<String, cfData> resultRow;
      Enumeration<? extends ZipArchiveEntry> files = zFile.getEntries();
      ZipArchiveEntry nextEntry = null;
      long size;
      double compressed;

      while (files.hasMoreElements()) {
        nextEntry = (ZipArchiveEntry) files.nextElement();
        resultRow = new FastMap<String, cfData>(8);
        resultRow.put("name", new cfStringData(nextEntry.getName()));
        resultRow.put("comment", new cfStringData(nextEntry.getComment()));
        resultRow.put("datelastmodified", new cfDateData(nextEntry.getTime()));

        if (nextEntry.isDirectory()) {
          resultRow.put("compressedsize", new cfNumberData(0));
          resultRow.put("size", new cfNumberData(0));
          resultRow.put("type", new cfStringData("Dir"));
          resultRow.put("compressedpercent", new cfNumberData(0));

        } else {
          size = nextEntry.getSize();
          resultRow.put(
              "compressedsize", new cfStringData(String.valueOf(nextEntry.getCompressedSize())));
          resultRow.put("size", new cfStringData(String.valueOf(size)));
          resultRow.put("type", new cfStringData("File"));
          if (size != 0) {
            compressed = ((float) nextEntry.getCompressedSize() / (float) size);
            resultRow.put(
                "compressedpercent",
                new cfStringData(String.valueOf(100 - (int) (compressed * 100))));
          } else {
            resultRow.put("compressedpercent", new cfStringData("0"));
          }
        }

        allResultRows.add(resultRow);
      }
      filesQuery.populateQuery(allResultRows);
      return filesQuery;
    } finally {
      try {
        zFile.close();
      } catch (IOException ignored) {
      }
    }
  }