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

Launcher can't open jar files where the offset of the manifest is >4GB

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: P3 P3
    • 25
    • None
    • tools

      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

            jpai Jaikiran Pai
            cushon Liam Miller-Cushon
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: