JDK-8328995 : Launcher can't open jar files where the offset of the manifest is >4GB
  • Type: Bug
  • Component: tools
  • Sub-Component: launcher
  • Priority: P3
  • Status: Open
  • Resolution: Unresolved
  • Submitted: 2024-03-25
  • Updated: 2024-09-12
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 24
24Unresolved
Related Reports
Relates :  
Description
The launcher doesn't have full zip64 support, and in particular can't open jar files where the offset of the manifest from the central directory is >4 GB in size.

Most zip implementations in the JDK have been updated to support the zip64 extension. See https://bugs.openjdk.org/browse/JDK-4681995 for java.util.jar changes, and https://bugs.openjdk.org/browse/JDK-7194005 for previous changes to the launcher for zip64 support.

References are from https://pkware.cachefly.net/webdocs/casestudies/APPNOTE.TXT.

From 4.5.3:

> If one of the size or offset fields in the Local or Central directory record is too small to hold the required data, a Zip64 extended information record is created.

When parse_manifest.c reads 'central directory header' entries (4.3.12), it assumes the values are present directly in the header, and does not inspect the 'Zip64 Extended Information Extra Field' (4.5.3).

When reading a zip64 file >4GB in size, it will read the 'relative offset of local header' from the central directory and assume it is a valid offset. It should check if that value is set to 0xFFFFFFFF and then look for a Zip64 extended information record:

https://github.com/openjdk/jdk/blob/fb8f2a0a929ebe7f65c69741712b89bbb403ade9/src/java.base/share/native/libjli/parse_manifest.c#L164-L165

---


Repro:

```
import static java.nio.charset.StandardCharsets.UTF_8;

import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;
import java.util.zip.CRC32;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class Zip64 {

  public static class Main {
    public static void main(String[] args) {
      System.out.print("Main");
    }
  }

  public static void main(String[] args) throws IOException {
    try (OutputStream fos = Files.newOutputStream(Paths.get(args[0]));
        BufferedOutputStream bos = new BufferedOutputStream(fos);
        ZipOutputStream zos = new ZipOutputStream(bos)) {

      byte[] gb = new byte[1 << 30];
      for (int i = 1; i <= 5; i++) {
        writeEntry(zos, Integer.toString(i), gb);
      }

      for (Class<?> clazz : List.of(Zip64.class, Main.class)) {
        String baseName = clazz.getName() + ".class";
        writeEntry(zos, baseName, Zip64.class.getResourceAsStream(baseName).readAllBytes());
      }

      writeEntry(
          zos,
          "META-INF/MANIFEST.MF",
          ("Manifest-Version: 1.0\nMain-Class: " + Main.class.getName() + "\n").getBytes(UTF_8));
    }
  }

  private static void writeEntry(ZipOutputStream zos, String name, byte[] bytes)
      throws IOException {
    ZipEntry ze = new ZipEntry(name);
    ze.setMethod(ZipEntry.STORED);
    ze.setSize(bytes.length);
    CRC32 crc = new CRC32();
    crc.update(bytes);
    ze.setCrc(crc.getValue());
    zos.putNextEntry(ze);
    zos.write(bytes);
    zos.closeEntry();
  }
}
```

$ java -fullversion
openjdk full version "22-ea+30-2287"

$ javac Zip64.java
$ java Zip64 zip64.jar

The expected behaviour is:

$ java -jar zip64.jar
Main

The actual behaviour is that the launcher fails to open the jar:

$ java -jar zip64.jar
Error: Invalid or corrupt jarfile zip64.jar
Comments
A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/20929 Date: 2024-09-10 06:15:57 +0000
12-09-2024

A pull request was submitted for review. Branch: master URL: https://git.openjdk.org/jdk/pull/18479 Date: 2024-03-25 21:37:03 +0000
09-07-2024