RFR(s): 8240235: jdk.test.lib.util.JarUtils updates jar files incorrectly

Volker Simonis volker.simonis at gmail.com
Fri Feb 28 18:47:42 UTC 2020


Hi,

can I please have a review for this small test fix:

http://cr.openjdk.java.net/~simonis/webrevs/2020/8240235/
https://bugs.openjdk.java.net/browse/JDK-8240235

JarUtils.updateJar() and JarUtils.updateJarFile() update jar files by
reading JarEntry-s from a source jar file and writing these exact
JarEntry-s to the destination jar file followed be the inflated and
re-deflated data belonging to this entry.

This approach is not correct, because JarEntry contains both, the
compressed and uncompressed size of the corresponding entry. But the
original Defalter which initially compressed that entry can be either
different from the current one or it might have used a different
compression level compared to the current Deflater which re-deflates
the entry data.

When the newly created entry is closed, the new compressed size will
be checked against the original compressed size if that was recorded
in the JarEntry and an exception will be thrown, when they differ:

java.util.zip.ZipException: invalid entry compressed size (expected
237 but got 238 bytes)
        at java.base/java.util.zip.ZipOutputStream.closeEntry(ZipOutputStream.java:267)
        at java.base/java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:192)
        at java.base/java.util.jar.JarOutputStream.putNextEntry(JarOutputStream.java:108)
        at jdk.test.lib.util.JarUtils.updateJar(JarUtils.java:294)
        at jdk.test.lib.util.JarUtils.updateJar(JarUtils.java:252)
        at HasUnsignedEntryTest.start(HasUnsignedEntryTest.java:77)
        at HasUnsignedEntryTest.main(HasUnsignedEntryTest.java:44)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native
Method)
        at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
        at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.base/java.lang.reflect.Method.invoke(Method.java:564)
        at com.sun.javatest.regtest.agent.MainWrapper$MainThread.run(MainWrapper.java:127)
        at java.base/java.lang.Thread.run(Thread.java:832)
        Suppressed: java.util.zip.ZipException: invalid entry
compressed size (expected 237 but got 238 bytes)
                at
java.base/java.util.zip.ZipOutputStream.closeEntry(ZipOutputStream.java:267)
                at
java.base/java.util.zip.ZipOutputStream.finish(ZipOutputStream.java:360)
                at
java.base/java.util.zip.DeflaterOutputStream.close(DeflaterOutputStream.java:237)
                at
java.base/java.util.zip.ZipOutputStream.close(ZipOutputStream.java:377)
                at jdk.test.lib.util.JarUtils.updateJar(JarUtils.java:280)

The fix is trivial. Instead of copying the JarEntry-s verbatim to the
output stream, simply write newly created JarEntry-s to the output
stream which only contain the entry name. This is also the way how
this is handled by the jar tool, when it updates jar files.

Thank you and best regards,
Volker


More information about the core-libs-dev mailing list