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)
======================================================================