6728376: Wrong error handling in Java_java_util_zip_Deflater_deflateBytes leads to size 0 if compress fails
authorsherman
Tue, 19 May 2009 16:21:48 -0700
changeset 2915 92e31faf9ffc
parent 2913 39a9cc073b84
child 2916 f8f76a2c1728
6728376: Wrong error handling in Java_java_util_zip_Deflater_deflateBytes leads to size 0 if compress fails 6735255: ZipFile.close() does not close ZipFileInputStreams, contrary to the API document Summary: Throws OOM when malloc failed. Closes all outstanding streams when closing Reviewed-by: alanb
jdk/src/share/classes/java/util/zip/ZipFile.java
jdk/src/share/native/java/util/zip/Deflater.c
jdk/src/share/native/java/util/zip/Inflater.c
--- a/jdk/src/share/classes/java/util/zip/ZipFile.java	Tue May 19 15:25:29 2009 -0700
+++ b/jdk/src/share/classes/java/util/zip/ZipFile.java	Tue May 19 16:21:48 2009 -0700
@@ -32,6 +32,8 @@
 import java.nio.charset.Charset;
 import java.util.Vector;
 import java.util.Enumeration;
+import java.util.Set;
+import java.util.HashSet;
 import java.util.NoSuchElementException;
 import static java.util.zip.ZipConstants64.*;
 
@@ -277,6 +279,9 @@
     // freeEntry releases the C jzentry struct.
     private static native void freeEntry(long jzfile, long jzentry);
 
+    // the outstanding inputstreams that need to be closed.
+    private Set<ZipFileInputStream> streams = new HashSet<ZipFileInputStream>();
+
     /**
      * Returns an input stream for reading the contents of the specified
      * zip file entry.
@@ -308,6 +313,7 @@
                 return null;
             }
             in = new ZipFileInputStream(jzentry);
+            streams.add(in);
         }
         final ZipFileInputStream zfin = in;
         switch (getEntryMethod(jzentry)) {
@@ -323,7 +329,7 @@
 
                 public void close() throws IOException {
                     if (!isClosed) {
-                         releaseInflater(inf);
+                        releaseInflater(inf);
                         this.in.close();
                         isClosed = true;
                     }
@@ -497,6 +503,13 @@
         synchronized (this) {
             closeRequested = true;
 
+            if (streams.size() !=0) {
+                Set<ZipFileInputStream> copy = streams;
+                streams = new HashSet<ZipFileInputStream>();
+                for (ZipFileInputStream is: copy)
+                    is.close();
+            }
+
             if (jzfile != 0) {
                 // Close the zip file
                 long zf = this.jzfile;
@@ -631,9 +644,9 @@
                     freeEntry(ZipFile.this.jzfile, jzentry);
                     jzentry = 0;
                 }
+                streams.remove(this);
             }
         }
-
     }
 
 
--- a/jdk/src/share/native/java/util/zip/Deflater.c	Tue May 19 15:25:29 2009 -0700
+++ b/jdk/src/share/native/java/util/zip/Deflater.c	Tue May 19 16:21:48 2009 -0700
@@ -138,6 +138,7 @@
 
             in_buf = (jbyte *) malloc(this_len);
             if (in_buf == 0) {
+                JNU_ThrowOutOfMemoryError(env, 0);
                 return 0;
             }
             (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
@@ -145,6 +146,7 @@
             out_buf = (jbyte *) malloc(len);
             if (out_buf == 0) {
                 free(in_buf);
+                JNU_ThrowOutOfMemoryError(env, 0);
                 return 0;
             }
 
@@ -179,6 +181,7 @@
 
             in_buf = (jbyte *) malloc(this_len);
             if (in_buf == 0) {
+                JNU_ThrowOutOfMemoryError(env, 0);
                 return 0;
             }
             (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
@@ -186,6 +189,7 @@
             out_buf = (jbyte *) malloc(len);
             if (out_buf == 0) {
                 free(in_buf);
+                JNU_ThrowOutOfMemoryError(env, 0);
                 return 0;
             }
 
--- a/jdk/src/share/native/java/util/zip/Inflater.c	Tue May 19 15:25:29 2009 -0700
+++ b/jdk/src/share/native/java/util/zip/Inflater.c	Tue May 19 16:21:48 2009 -0700
@@ -125,6 +125,7 @@
 
         in_buf = (jbyte *) malloc(this_len);
         if (in_buf == 0) {
+            JNU_ThrowOutOfMemoryError(env, 0);
             return 0;
         }
         (*env)->GetByteArrayRegion(env, this_buf, this_off, this_len, in_buf);
@@ -132,6 +133,7 @@
         out_buf = (jbyte *) malloc(len);
         if (out_buf == 0) {
             free(in_buf);
+            JNU_ThrowOutOfMemoryError(env, 0);
             return 0;
         }