-
Bug
-
Resolution: Fixed
-
P4
-
11, 16, 18
-
b06
-
generic
-
generic
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8340581 | 17.0.14 | Goetz Lindenmaier | P4 | Resolved | Fixed | b01 |
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
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
- backported by
-
JDK-8340581 ZipFile can't open big file (NegativeArraySizeException)
-
- Resolved
-
- links to
-
Commit openjdk/jdk/848b16a3
-
Commit(master) openjdk/jdk17u-dev/4120fcc8
-
Review openjdk/jdk/6927
-
Review(master) openjdk/jdk17u-dev/2900