8186464: ZipFile cannot read some InfoZip ZIP64 zip files#835
Conversation
Co-authored-by: Andrew John Hughes <andrew@openjdk.org> Backport-of: 02b9452ed39eccdfe3210e65b17d4759333c0f15
|
👋 Welcome back fitzsim! A progress list of the required criteria for merging this PR into |
|
❗ This change is not yet ready to be integrated. |
|
This backport pull request has now been updated with issue from the original commit. |
|
/contributor add Andrew John Hughes andrew@openjdk.org |
|
@fitzsim |
|
The latest CI run had the same certificate issues I mentioned in the description, and a new error running |
We would like to backport JDK-8186464: ZipFile cannot read some InfoZip ZIP64 zip files that was fixed during the development of
OpenJDK 10.(This is a third attempt at #452, hopefully this time with clearer background and context.)
Background
In the
OpenJDK 9timeframe, thejava.util.zip.ZipFilewas rewritten to be pure Java, by:JDK-8145260 To bring j.u.z.ZipFile's native implementation to Java to remove the expensive jni cost and mmap crash risk
This rewrite was never backported to
OpenJDK 8and would be too invasive and risky to backport in its entirety now.This means that
OpenJDK 8'sjava.util.zip.ZipFileimplementation is backed byJNIC code, implemented injdk8u/jdk/src/share/native/java/util/zip/zip_util.c(core algorithms) andjdk8u/jdk/src/share/native/java/util/zip/ZipFile.c(JNI wrapper C code).ZipFile.cwas deleted during development ofOpenJDK 9, in theJDK-8145260commit:openjdk/jdk9u@2b91819
OpenJDK 8also contains Zip algorithms in a pure Java demo library, underjdk8u/jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs, added during development ofOpenJDK 7, by:JDK-6990846 Demo: NIO.2 filesystem provider for zip/jar archives
During development of
OpenJDK 9, this pure Java code was promoted from being a demo package to being a fully-supported package, by:JDK-8038500: (zipfs) Upgrade ZIP provider to be a supported provider
It remains demo-only in
OpenJDK 8, and there are no plans to backport the promotion change toOpenJDK 8.Desired Java-to-C backport, example RPM patch
The original JDK-8186464 fix was made against the pure Java
ZipFile.javaimplementation.The same logic of the pure Java JDK-8186464 fixes applies readily to the core C algorithms in
zip_util.c. Andrew has converted the Java code in the original fix to C code applied tozip_util.c.OpenJDK 8users have run into this issue in real-world applications so in our Red Hat RPMs, since 2020, we have been shipping and maintaining "downstream" a backport patch.This Red Hat internal backport patch, in addition to fixing the C code, also updates the pure Java
ZipFileSystem.javacode which was affected by the same issue reported in JDK-8186464.ZipFileSystem.javahas demo status inOpenJDK 8, but was promoted to production status inOpenJDK 9. The pure JavaZipFileSystem.javapart of the backport patch is somewhat incidental, since, as established in the background section, the production/important Zip algorithms inOpenJDK 8are in the C implementation backingZipFile.java. We suspectZipFileSystem.javais little-used byOpenJDK 8users.These changes have been deployed to Red Hat customers since 2020, with minor updates from time-to-time as required to keep the patch applicable.
Here is the most recent patch, written and maintained by Andrew Hughes:
https://gitlab.com/redhat/centos-stream/rpms/java-1.8.0-openjdk/-/raw/openjdk-portable-centos-9/jdk8186464-rh1433262-zip64_failure.patch?ref_type=72646f68c8ccb1bdbee3d2249abccf90980eb7d6
Specific Backport Notes
ReadZip.java
On jdk11u-dev master branch, ReadZip.java has these changes beyond what is currently on jdk8u-dev master (ordered oldest to newest):
JDK-8145260: To bring j.u.z.ZipFile's native implementation to Java to remove the expensive jni cost and mmap crash risk [2]
JDK-6233323: ZipEntry.isDirectory() may return false incorrectly 8144977: Class.getResourceAsStream("directory") in JAR returns broken InputStream
JDK-8187443: Forest Consolidation: Move files to unified layout
JDK-8186464: ZipFile cannot read some InfoZip ZIP64 zip files
JDK-8199616: Fix @module declarations in tier1 tests
Meanwhile, jdk8u-dev master saw this change, which did not go to jdk11u-dev master:
JDK-8184993: Jar file verification failing with SecurityException: digest missing xxx
Backporting the 8186464-specific ReadZip.java hunks required adjustments throughout the file and a location change due to forest consolidation.
The net result is that the two tests of ZIP64 end records are the same in jdk8u-dev and jdk11u-dev, other than the use of 11 syntax conveniences
Map.ofandIOUtils.readAllBytes.ZipFileSystem.java
On jdk11u-dev master, ZipFileSystem.java has been through three
location changes since it had the same location as it does today on
jdk8u-dev master:
JDK-6989148: (fs) zip provider should be available "out of the box"
=> ./jdk/src/share/demo/nio/zipfs/src/com/sun/nio/zipfs/ZipFileSystem.javaJDK-8038500: (zipfs) Upgrade ZIP provider to be a supported provider
=> ./jdk/src/share/classes/jdk/nio/zipfs/ZipFileSystem.javaJDK-8054834: Modular Source Code
=> ./jdk/src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.javaJDK-8187443: Forest Consolidation: Move files to unified layout
=> ./src/jdk.zipfs/share/classes/jdk/nio/zipfs/ZipFileSystem.javaThere are too many divergences between jdk8u-dev and jdk11u-dev to list, so this rework also had to be done fully by hand.
The net result is that with this jdk8u-dev patch the
ZipFileSystem.findENDfunction identical to jdk11u-dev.ZipFile.java
"Initial load"
=> ./jdk/src/share/classes/java/util/zip/ZipFile.javaJDK-8054834: Modular Source Code
=> ./jdk/src/java.base/share/classes/java/util/zip/ZipFile.javaJDK-8187443: Forest Consolidation: Move files to unified layout
=> ./src/java.base/share/classes/java/util/zip/ZipFile.javaAs mentioned in the background section, this is the file that required unique treatment, a Java-to-C port, for jdk8u-dev.
Andrew ported this Java code (annotated for this pull request with [comment: ...] blocks:
to this C code:
The older compiler on the Microsoft Windows x32 build machine needed the
end64bufdeclaration to be at the start of the function; I made that change on top of Andrew's patch.Testing
When working on #442 I also tested this same code with the test steps in the description of the JBS issue JDK-8186464: ZipFile cannot read some InfoZip ZIP64 zip files.
I re-confirmed that the changes to ReadZip.java exercise the new code
zip_utils.ccode and produce correct results.CI runs showed no regressions due to this patch. There are unrelated certificate issues in some of the tests that cause the test runs to fail, for example:
Newer OpenJDK versions and zip_util.c
zip_util.cstill survives in newer versions up to and including tip (i.e.,OpenJDK 27).It is used to load Zip files from the bootstrap classpath (
-Xbootclasspath), which happens during JVM bring-up, prior to Java features (such as the pure Java ZipFile implementation) being available.Conceivably newer versions of
zip_util.ccould be patched in the same was as proposed here, however no one has ever needed to load InfoZip ZIP64 zip files on the bootstrap classpath.There was not much interest when I proposed this in:
JDK-8334048: -Xbootclasspath can not read some ZIP64 zip files
openjdk/jdk#19678
(This could have subsequently become a true backport to
OpenJDK 8zip_util.c.)In summary, given that no one needs this code in
zip_util.cin new OpenJDK versions due tozip_util.conly being used in very specific circumstances, and given its importance inOpenJDK 8as backing the sole production Zip API, I think it makes more sense just to patchzip_util.conly inOpenJDK 8directly as we're proposing in this pull request.Progress
Issue
Contributors
<andrew@openjdk.org>Reviewing
Using
gitCheckout this PR locally:
$ git fetch https://git.openjdk.org/jdk8u-dev.git pull/835/head:pull/835$ git checkout pull/835Update a local copy of the PR:
$ git checkout pull/835$ git pull https://git.openjdk.org/jdk8u-dev.git pull/835/headUsing Skara CLI tools
Checkout this PR locally:
$ git pr checkout 835View PR using the GUI difftool:
$ git pr show -t 835Using diff file
Download this PR as a diff file:
https://git.openjdk.org/jdk8u-dev/pull/835.diff
Using Webrev
Link to Webrev Comment