JDK-6419239 : jar can add files to an archive that it can't later extract
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.util.jar
  • Affected Version: 1.4.2_06
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: solaris
  • CPU: generic
  • Submitted: 2006-04-27
  • Updated: 2010-04-03
  • Resolved: 2009-03-20
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.
Other
1.4.2_21 b01Fixed
Related Reports
Relates :  
Description
The java 1.4 version of the jar command (both 32-bit and 64-bit) can not extract files that are larger than 2^31-1 (2147483647). However, it can add files that are larger than this. The result is that you can have an archive with files in it that can not be extracted without getting a ZipException like this:

java.util.zip.ZipException: invalid entry size (expected 2920611840 but got -1374355456 bytes)

This is a classic signed int overflow situation -- -1374355456 == unsigned 2920611840

java 1.5 and later does not have this problem

Here is a test case

+ /usr/sbin/mkfile -n 2147483648 2147483648
+ /usr/j2se/bin/java -version
java version "1.4.2_06"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.2_06-b03)
Java HotSpot(TM) Client VM (build 1.4.2_06-b03, mixed mode)
+ /usr/j2se/bin/jar cvf test.jar 2147483648
added manifest
adding: 2147483648(in = -2147483648) (out= 2087262)(deflated 100%)
+ /usr/j2se/bin/jar tvf test.jar
     0 Thu Apr 27 13:01:34 PDT 2006 META-INF/
    71 Thu Apr 27 13:01:34 PDT 2006 META-INF/MANIFEST.MF
java.util.zip.ZipException: invalid entry size (expected 2147483648 but got -2147483648 bytes)
        at java.util.zip.ZipInputStream.readEnd(ZipInputStream.java:367)
        at java.util.zip.ZipInputStream.read(ZipInputStream.java:141)
        at java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:91)
        at sun.tools.jar.Main.list(Main.java:744)
        at sun.tools.jar.Main.run(Main.java:192)
        at sun.tools.jar.Main.main(Main.java:904)

Comments
EVALUATION Only an issue in 1.4.2 because Inflater.getTotalOut() returns an int. In 5.0 onwards, we use Inflater.getBytesWritten() which returns a long.
29-12-2008

SUGGESTED FIX The comparison that fails compares a long with an int, which gets sign-extended to a long and becomes negative. To use this as a 32-bit unsigned integer in src/share/classes/java/util/zip/ZipInputStream.java in method readEnd: $ sccs diffs -C src/share/classes/java/util/zip/ZipInputStream.java ------- ZipInputStream.java ------- *** /tmp/sccs.0maGmG Mon Dec 29 13:43:28 2008 --- src/share/classes/java/util/zip/ZipInputStream.java Mon Dec 29 09:58:23 2008 *************** *** 368,374 **** e.size = get32(tmpbuf, EXTLEN); } } ! if (e.size != inf.getTotalOut()) { throw new ZipException( "invalid entry size (expected " + e.size + " but got " + inf.getTotalOut() + " bytes)"); --- 368,374 ---- e.size = get32(tmpbuf, EXTLEN); } } ! if (e.size != (inf.getTotalOut() & 0xFFFFFFFFL) ) { throw new ZipException( "invalid entry size (expected " + e.size + " but got " + inf.getTotalOut() + " bytes)");
29-12-2008

EVALUATION The evaluation of bug 4262583 describes the issue, and the solution which (IIRC) was used in the fix for JDK 1.5. In particular, it notes: <snip> One very good reason to fix this is that currently a user can use the "jar" command to create a jar file that cannot be read by "jar". </snip>
14-01-2008