Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4406823

Dup entry in Zip/JarOutputStream causes corrupt file to be produced (cf#112217)

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 1.4.0
    • 1.3.0
    • core-libs
    • beta2
    • x86
    • windows_98, windows_nt
    • Verified



      Name: boT120536 Date: 01/22/2001


      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
      Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)


      If I construct a jar file using the JarOutputStream, and using putNextEntry(),
      I add a duplicate entry, a corrupt jar file is produced. I get this error
      message when doing a "jar tvf mybad.jar"

      java.util.zip.ZipException: invalid stored block lengths
              at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:140)
              at java.util.zip.ZipInputStream.read(ZipInputStream.java:138)
               ...(didn't include the rest)...

      If I trap duplicates and don't try adding them, the file is OK.

      I noticed in the source for ZipOutputStream in the putNextEntry() method, a
      check is done for duplicate entries, but it is after the writeLOC(e) call which
      puts the local file header into the zip stream even though the file won't be
      written.
      (Review ID: 110419)
      ======================================================================

      Name: boT120536 Date: 01/22/2001


      java version "1.2.2"
      Classic VM (build JDK-1.2.2-001, native threads, symcjit)

      and

      java version "1.3.0"
      Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
      Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)




      Due to our build process, we create multiple jar files with multiple
      manifests. I wrote a JARAggregator class which combines multiple jar files
      into one jar file and combines the contents of the manifest. When doing it,
      the jar output file can be used on the classpath line correctly; however the
      output file cannot be accessed using the jar tool.

      There are two problems
      If you try to add a duplicate entry, the jar file becomes corrupted

      Here is a test case. The problem occurs when copying from one jar file to
      another using JarInputStream and JarOutputStream. Invoke it by "JarTest
      inJar.jar outJar.jar" where inJar is any jar of size.

      Then run

      tar tf outJar.jar

      And ad after the first file you'll get...

      java.util.zip.ZipException: invalid stored block lengths
              at java.util.zip.InflaterInputStream.read(InflaterInputStream.java:140)
              at java.util.zip.ZipInputStream.read(ZipInputStream.java:138)
              at java.util.zip.ZipInputStream.closeEntry(ZipInputStream.java:96)
              at sun.tools.jar.Main.list(Main.java:705)
              at sun.tools.jar.Main.run(Main.java:192)
              at sun.tools.jar.Main.main(Main.java:778)

      This seems as if it is caused by writeLOC being executed before the testing of
      the entry being a duplicate in ZipOutputStream.putNextEntry()


      import java.io.*;
      import java.util.*;
      import java.util.jar.*;
      import java.util.zip.*;

      public class JarTest {
          public static void main(String[] args) throws java.io.IOException {
      File inFile = new File(args[0]);
      File outFile = new File(args[1]);
      JarFile inJar = new JarFile(inFile);
      OutputStream fout = new FileOutputStream(outFile);
      JarOutputStream out = new JarOutputStream(fout);
           
      byte[] buf = new byte[1024];
      int available;
      for (Enumeration entries = inJar.entries(); entries.hasMoreElements();){
      JarEntry entry = (JarEntry) entries.nextElement();
      InputStream in = inJar.getInputStream(entry);
      try {
      JarEntry newEntry = (JarEntry) entry.clone();
      newEntry.setCompressedSize(-1);
      out.putNextEntry(newEntry);
      while ((available = in.read(buf)) != -1) {
      out.write(buf, 0, available);
      }
      out.closeEntry();
      }
      catch (ZipException ex) {
      ex.printStackTrace();
      return;
      }
      finally {
      out.closeEntry();
      }
      try {
      out.putNextEntry(new JarEntry(entry.getName()));
      }
      catch (ZipException ex) {
      // supposed to be here
      }

      }
      out.close();
          }
      }
      (Review ID: 112217)
      ======================================================================

            kkladkosunw Konstantin Kladko (Inactive)
            bonealsunw Bret O'neal (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: