changeset 17259:160ce50dd2e8

8184306: zlib 1.2.11 upgrade triggers j.u.zip.Deflater regression Reviewed-by: alanb, bpb
author sherman
date Mon, 17 Jul 2017 14:48:43 -0700
parents 1a1dc330c930
children 06df1ce4b9b8
files src/java.base/share/native/libzip/zlib/deflate.c src/java.base/share/native/libzip/zlib/patches/ChangeLog_java test/java/util/zip/DeInflate.java
diffstat 3 files changed, 92 insertions(+), 29 deletions(-) [+]
line wrap: on
line diff
--- a/src/java.base/share/native/libzip/zlib/deflate.c	Thu Jul 13 19:34:42 2017 +0000
+++ b/src/java.base/share/native/libzip/zlib/deflate.c	Mon Jul 17 14:48:43 2017 -0700
@@ -505,6 +505,8 @@
     s->pending = 0;
     s->pending_out = s->pending_buf;
 
+    s->high_water = 0;      /* reset to its inital value 0 */
+
     if (s->wrap < 0) {
         s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
     }
--- a/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java	Thu Jul 13 19:34:42 2017 +0000
+++ b/src/java.base/share/native/libzip/zlib/patches/ChangeLog_java	Mon Jul 17 14:48:43 2017 -0700
@@ -76,6 +76,21 @@
 >                 n = len;
 --------------------------
 
+(6) deflate.c  #8184306
 
+*** 503,512 ****
+--- 503,514 ----
+  
+      s = (deflate_state *)strm->state;
+      s->pending = 0;
+      s->pending_out = s->pending_buf;
+  
++     s->high_water = 0;      /* reset to its inital value 0 */
++ 
+      if (s->wrap < 0) {
+          s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
+      }
+      s->status =
+  #ifdef GZIP
 
   
--- a/test/java/util/zip/DeInflate.java	Thu Jul 13 19:34:42 2017 +0000
+++ b/test/java/util/zip/DeInflate.java	Mon Jul 17 14:48:43 2017 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
 
 /**
  * @test
- * @bug 7110149
+ * @bug 7110149 8184306
  * @summary Test basic deflater & inflater functionality
  * @key randomness
  */
@@ -34,64 +34,110 @@
 
 public class DeInflate {
 
-    static void check(Deflater compresser, byte[] in, int len,
+    static void checkStream(Deflater def, byte[] in, int len,
+                            byte[] out1, byte[] out2, boolean nowrap)
+        throws Throwable
+    {
+        Arrays.fill(out1, (byte)0);
+        Arrays.fill(out2, (byte)0);
+
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        try (DeflaterOutputStream defos = new DeflaterOutputStream(baos, def)) {
+            defos.write(in, 0, len);
+        }
+        out1 = baos.toByteArray();
+        int m = out1.length;
+
+        Inflater inf = new Inflater(nowrap);
+        inf.setInput(out1, 0, m);
+        int n = inf.inflate(out2);
+
+        if (n != len ||
+            !Arrays.equals(Arrays.copyOf(in, len), Arrays.copyOf(out2, len)) ||
+            inf.inflate(out2) != 0) {
+            System.out.printf("m=%d, n=%d, len=%d, eq=%b%n",
+                              m, n, len, Arrays.equals(in, out2));
+            throw new RuntimeException("De/inflater failed:" + def);
+        }
+    }
+
+    static void check(Deflater def, byte[] in, int len,
                       byte[] out1, byte[] out2, boolean nowrap)
         throws Throwable
     {
         Arrays.fill(out1, (byte)0);
         Arrays.fill(out2, (byte)0);
 
-        compresser.setInput(in, 0, len);
-        compresser.finish();
-        int m = compresser.deflate(out1);
+        def.setInput(in, 0, len);
+        def.finish();
+        int m = def.deflate(out1);
 
-        Inflater decompresser = new Inflater(nowrap);
-        decompresser.setInput(out1, 0, m);
-        int n = decompresser.inflate(out2);
+        Inflater inf = new Inflater(nowrap);
+        inf.setInput(out1, 0, m);
+        int n = inf.inflate(out2);
 
         if (n != len ||
             !Arrays.equals(Arrays.copyOf(in, len), Arrays.copyOf(out2, len)) ||
-            decompresser.inflate(out2) != 0) {
+            inf.inflate(out2) != 0) {
             System.out.printf("m=%d, n=%d, len=%d, eq=%b%n",
                               m, n, len, Arrays.equals(in, out2));
-            throw new RuntimeException("De/inflater failed:" + compresser);
+            throw new RuntimeException("De/inflater failed:" + def);
         }
     }
 
+    private static Deflater newDeflater(int level, int strategy, boolean dowrap, byte[] tmp) {
+        Deflater def = new Deflater(level, dowrap);
+        if (strategy != Deflater.DEFAULT_STRATEGY) {
+            def.setStrategy(strategy);
+            // The first invocation after setLevel/Strategy()
+            // with a different level/stragety returns 0, if
+            // there is no need to flush out anything for the
+            // previous setting/"data", this is tricky and
+            // appears un-documented.
+            def.deflate(tmp);
+        }
+        return def;
+    }
+
+    private static Deflater resetDeflater(Deflater def, int level, int strategy) {
+        def.setLevel(level);
+        def.setStrategy(strategy);
+        def.reset();
+        return def;
+    }
+
     public static void main(String[] args) throws Throwable {
+
         byte[] dataIn = new byte[1024 * 512];
         new Random().nextBytes(dataIn);
         byte[] dataOut1 = new byte[dataIn.length + 1024];
         byte[] dataOut2 = new byte[dataIn.length];
-        boolean wrap[] = new boolean[] { false, true };
+
+        Deflater defNotWrap = new Deflater(Deflater.DEFAULT_COMPRESSION, false);
+        Deflater defWrap = new Deflater(Deflater.DEFAULT_COMPRESSION, true);
 
         for (int level = Deflater.DEFAULT_COMPRESSION;
                  level <= Deflater.BEST_COMPRESSION; level++) {
-            System.out.print("level=" + level + ", strategy= ");
             for (int strategy = Deflater.DEFAULT_STRATEGY;
                      strategy <= Deflater.HUFFMAN_ONLY; strategy++) {
-                System.out.print(" " + strategy + " nowrap[");
-                for (int dowrap = 0; dowrap <= 1; dowrap++) {
-                    System.out.print(" " + wrap[dowrap]);
+                for (boolean dowrap : new boolean[] { false, true }) {
+                    System.out.println("level:" + level +
+                                     ", strategy: " + strategy +
+                                     ", dowrap: " + dowrap);
                     for (int i = 0; i < 5; i++) {
-                        Deflater def = new Deflater(level, wrap[dowrap]);
-                        if (strategy != Deflater.DEFAULT_STRATEGY) {
-                            def.setStrategy(strategy);
-                            // The first invocation after setLevel/Strategy()
-                            // with a different level/stragety returns 0, if
-                            // there is no need to flush out anything for the
-                            // previous setting/"data", this is tricky and
-                            // appears un-documented.
-                            def.deflate(dataOut2);
-                        }
                         int len = (i == 0)? dataIn.length
                                           : new Random().nextInt(dataIn.length);
-                            check(def, dataIn, len, dataOut1, dataOut2, wrap[dowrap]);
+                        // use a new deflater
+                        Deflater def = newDeflater(level, strategy, dowrap, dataOut2);
+                        check(def, dataIn, len, dataOut1, dataOut2, dowrap);
+
+                        // reuse the deflater (with reset) and test on stream, which
+                        // uses a "smaller" buffer (smaller than the overall data)
+                        def = resetDeflater(dowrap ? defWrap : defNotWrap, level, strategy);
+                        checkStream(def, dataIn, len, dataOut1, dataOut2, dowrap);
                     }
                 }
-                System.out.print("] ");
             }
-            System.out.println();
         }
     }
 }