-
Bug
-
Resolution: Fixed
-
P4
-
8, 9
-
b08
-
x86_64
-
windows_7
-
Verified
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8275965 | 17.0.2 | Yuri Nesterenko | P4 | Resolved | Fixed | b03 |
JDK-8275919 | 15.0.6 | Yuri Nesterenko | P4 | Resolved | Fixed | b02 |
JDK-8275915 | 13.0.10 | Yuri Nesterenko | P4 | Resolved | Fixed | b02 |
JDK-8276087 | 11.0.14 | Yuri Nesterenko | P4 | Resolved | Fixed | b01 |
JDK-8284570 | openjdk8u342 | Yuri Nesterenko | P4 | Resolved | Fixed | b01 |
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
EXTRA RELEVANT SYSTEM CONFIGURATION :
Should probably work anywhere, as it seems to be a bug in the java code.
A DESCRIPTION OF THE PROBLEM :
When a zip file is openend to overwrite an existing entry, a ByteArrayOutputStream is created with the initial size of the existing entry. However, the size argument is an int, so if the size of the existing entry is somewhere between 2^31 and 2 ^32 (i.e. between 2 and 4 GB), the int will be negative, resulting in an IllegalArgumentException.
I didn't check what happens if the size is even larger than 2^32.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute the code below.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Getting an OutputStream in which I can write the new content of the zip file entry.
ACTUAL -
IllegalArgumentException.
ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.IllegalArgumentException: Negative initial size: -2147479552
at java.io.ByteArrayOutputStream.<init>(ByteArrayOutputStream.java:74)
at com.sun.nio.zipfs.ZipFileSystem.getOutputStream(ZipFileSystem.java:1378)
at com.sun.nio.zipfs.ZipFileSystem.newOutputStream(ZipFileSystem.java:524)
at com.sun.nio.zipfs.ZipPath.newOutputStream(ZipPath.java:792)
at com.sun.nio.zipfs.ZipFileSystemProvider.newOutputStream(ZipFileSystemProvider.java:285)
at java.nio.file.Files.newOutputStream(Files.java:216)
at ZipFileSystemBug.main(ZipFileSystemBug.java:33)
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.io.File;
import java.io.OutputStream;
import java.net.URI;
import java.nio.file.FileSystem;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.StandardOpenOption;
import java.util.HashMap;
import java.util.Map;
public class ZipFileSystemBug {
public static void main(String[] args) throws Exception {
// Preparation: Create a Zip file with an entry larger than 2^31 bytes.
File file = File.createTempFile("large", ".zip");
file.delete();
final URI uri = URI.create("jar:" + file.toURI());
final Map<String, Object> env = new HashMap<>();
env.put("create", "true");
// Uncomment this for a temporary fix using the file system instead of memory (undocumented feature?)
// env.put("useTempFile", Boolean.TRUE);
System.out.println(uri);
try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
byte[] buf = new byte[4096];
try (OutputStream out = Files.newOutputStream(fs.getPath("large"), StandardOpenOption.CREATE)) {
for (int i = 0; i < 524289; i++) {
out.write(buf);
}
}
}
// Try to rewrite that file:
try (FileSystem fs = FileSystems.newFileSystem(uri, env)) {
Files.newOutputStream(fs.getPath("large"), StandardOpenOption.WRITE);
} finally {
// Cleanup.
file.delete();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
You can bypass the problem by setting "useTempFile" to Boolean.TRUE (see comment in code).
- backported by
-
JDK-8275915 (zipfs): Accessing a large entry (> 2^31 bytes) leads to a negative initial size for ByteArrayOutputStream
- Resolved
-
JDK-8275919 (zipfs): Accessing a large entry (> 2^31 bytes) leads to a negative initial size for ByteArrayOutputStream
- Resolved
-
JDK-8275965 (zipfs): Accessing a large entry (> 2^31 bytes) leads to a negative initial size for ByteArrayOutputStream
- Resolved
-
JDK-8276087 (zipfs): Accessing a large entry (> 2^31 bytes) leads to a negative initial size for ByteArrayOutputStream
- Resolved
-
JDK-8284570 (zipfs): Accessing a large entry (> 2^31 bytes) leads to a negative initial size for ByteArrayOutputStream
- Resolved
- duplicates
-
JDK-8011146 (zipfs) newOutputStream should automatically spill into temporary file when output stream grows too big
- Closed
- relates to
-
JDK-8279536 jdk/nio/zipfs/ZipFSOutputStreamTest.java timed out
- Closed
- links to
-
Commit openjdk/jdk8u-dev/3647d987
-
Commit openjdk/jdk11u-dev/8a9cda2d
-
Commit openjdk/jdk13u-dev/9cd4e475
-
Commit openjdk/jdk15u-dev/d38d207a
-
Commit openjdk/jdk17u/ccfe697f
-
Commit openjdk/jdk/c3d8e922
-
Review openjdk/jdk8u-dev/17
-
Review openjdk/jdk11u-dev/545
-
Review openjdk/jdk13u-dev/275
-
Review openjdk/jdk15u-dev/116
-
Review openjdk/jdk17u/201
-
Review openjdk/jdk/4607