United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6419239 jar can add files to an archive that it can't later extract
JDK-6419239 : jar can add files to an archive that it can't later extract

Details
Type:
Bug
Submit Date:
2006-04-27
Status:
Resolved
Updated Date:
2010-04-03
Project Name:
JDK
Resolved Date:
2009-03-20
Component:
core-libs
OS:
solaris
Sub-Component:
java.util.jar
CPU:
generic
Priority:
P2
Resolution:
Fixed
Affected Versions:
1.4.2_06
Fixed Versions:
1.4.2_21 (b01)

Related Reports
Relates:

Sub Tasks

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

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>
                                     
2008-01-14
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)");
                                     
2008-12-29
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.
                                     
2008-12-29



Hardware and Software, Engineered to Work Together