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

ZipFile can't open big file (NegativeArraySizeException)

XMLWordPrintable

    • b06
    • generic
    • generic

        ADDITIONAL SYSTEM INFORMATION :
        Ubuntu Linux 20.04, Amazon Corretto 15.0.2, Amazon Corretto 16.0.2

        A DESCRIPTION OF THE PROBLEM :
        ZipFile tries to read CEN into array, but it is larger than 2Gb. Java8 use native library and works fine, as well as native linux unzip.

        Opening large file throws exception:
        java.lang.NegativeArraySizeException: -1319967274
          at java.base/java.util.zip.ZipFile$Source.initCEN(ZipFile.java:1487)
          ...

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        Test class provided. Works about 1 hour on my machine, because of creating about 7Gb zip file.

        EXPECTED VERSUS ACTUAL BEHAVIOR :
        EXPECTED -
        No exceptions, file read as usual.
        ACTUAL -
        java.lang.NegativeArraySizeException

        ---------- BEGIN SOURCE ----------
        public class BadZipTest {
        File hugeZipFile;

        @BeforeEach
        void setUp() throws Exception {
        hugeZipFile = File.createTempFile("hugeZip", ".zip");
        }

        @AfterEach
        void tearDown() throws Exception {
        hugeZipFile.delete();
        }

        @Test
        void testParseBigZipCEN() throws Exception {
        long startTime = System.currentTimeMillis();
        try (ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(hugeZipFile))) {
        int dirCount = 25_000;
        long nextLog = System.currentTimeMillis();
        for (int dirN = 0; dirN < dirCount; dirN++) {
        String dirName = UUID.randomUUID() + "/";
        for (int fileN = 0; fileN < 1_000; fileN++) {
        ZipEntry entry = new ZipEntry(dirName + UUID.randomUUID());
        zip.putNextEntry(entry);
        zip.closeEntry(); // all files are empty
        }
        if (System.currentTimeMillis() >= nextLog) {
        nextLog = 30_000 + System.currentTimeMillis();
        System.out.printf("Processed %s%% directories (%s), file size is %sMb (%ss)%n",
        dirN * 100 / dirCount, dirN, hugeZipFile.length() / 1024 / 1024,
        (System.currentTimeMillis() - startTime) / 1000);
        }
        }
        }
        System.out.printf("File generated in %ss, file size is %sMb%n",
        (System.currentTimeMillis() - startTime) / 1000, hugeZipFile.length() / 1024 / 1024);

        // the exception thrown here
        // java.lang.NegativeArraySizeException: -1319967274
        // at java.base/java.util.zip.ZipFile$Source.initCEN(ZipFile.java:1487)
        try (ZipFile zip = new ZipFile(hugeZipFile)) {
        assertTrue(zip.entries().hasMoreElements());
        }
        }
        }
        ---------- END SOURCE ----------

        CUSTOMER SUBMITTED WORKAROUND :
        ZipInputStream works fine, if you don't need to navigate over zip internals.

        FREQUENCY : always


              lancea Lance Andersen
              webbuggrp Webbug Group
              Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

                Created:
                Updated:
                Resolved: