JDK-7077769 : (zipfs) ZipFileSystem.writeCEN() writes wrong "data size" for ZIP64 extended information extra field
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.nio
  • Affected Version: 7
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 2011-08-11
  • Updated: 2011-09-02
  • Resolved: 2011-09-02
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7 JDK 8
7u2 b06Fixed 8Fixed
Description
(1)The extra field for ZIP64 (and any other type of extra field data block) has the
format 

header ID (2 bytes)
data size (2 bytes)
data block

The "data size" is the "size of data following", which does NOT inlclude the
2 + 2 bytes for the headerID + data size.

We does it correct in ZipOutputStream.writeLOC/CEN, we do it correct in
ZipFileSystem.writeLOC(). But unfortunately it appears we accidently included
the 4 byte header (id + size) in ZipFileSystem.writeCEN(), as showed below

           if (csize >= ZIP64_MINVAL) {
                csize0 = ZIP64_MINVAL;
                elen64 += 8;                 // csize(8)
            }
            if (size >= ZIP64_MINVAL) {
                size0 = ZIP64_MINVAL;        // size(8)
                elen64 += 8;
            }
            if (locoff >= ZIP64_MINVAL) {
                locoff0 = ZIP64_MINVAL;
                elen64 += 8;                 // offset(8)
            }
            if (elen64 != 0)
                elen64 += 4;                 // header and data sz 4 bytes

            ...
            if (elen64 != 0) {
                writeShort(os, EXTID_ZIP64);// Zip64 extra
                writeShort(os, elen64);     // size of "this" extra block
                if (size0 == ZIP64_MINVAL)
                    writeLong(os, size);
                if (csize0 == ZIP64_MINVAL)
                    writeLong(os, csize);
                if (locoff0 == ZIP64_MINVAL)
                    writeLong(os, locoff);
            }

(2) ZipFileSystem.sync()

   OutputStream os = Files.newOutputStream(tmpFile, WRITE);

It appears we are not wrapping the "os" with a BufferedOutputSteam, which might slow
down the sync() when writing loc and cen tables, especially if we have lots of entries
in the archive.

Comments
EVALUATION Need to fix in 7u2.
11-08-2011