25eec2b
From 0c7af9e6cb05b436505e7f46ef49dcb6f791f30a Mon Sep 17 00:00:00 2001
25eec2b
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppisar@redhat.com>
25eec2b
Date: Fri, 17 Feb 2017 11:00:21 +0100
25eec2b
Subject: [PATCH] Adapt to zlib-1.2.11
25eec2b
MIME-Version: 1.0
25eec2b
Content-Type: text/plain; charset=UTF-8
25eec2b
Content-Transfer-Encoding: 8bit
25eec2b
25eec2b
This is a fix ported from Compress-Raw-Zlib-2.072 that restores
25eec2b
compatibility with zlib-1.2.11.
25eec2b
25eec2b
CPAN RT#119762
25eec2b
25eec2b
Signed-off-by: Petr Písař <ppisar@redhat.com>
25eec2b
---
25eec2b
 Zlib.xs    | 220 +++++++++++++++++++++++++++++++++++++++++++++++--------------
25eec2b
 t/02zlib.t |  11 +++-
25eec2b
 2 files changed, 178 insertions(+), 53 deletions(-)
25eec2b
25eec2b
diff --git a/Zlib.xs b/Zlib.xs
25eec2b
index d379f78..83d1423 100644
25eec2b
--- a/Zlib.xs
25eec2b
+++ b/Zlib.xs
25eec2b
@@ -74,6 +74,10 @@
25eec2b
 #  define AT_LEAST_ZLIB_1_2_8
25eec2b
 #endif
25eec2b
 
25eec2b
+#if  defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1290
25eec2b
+#  define AT_LEAST_ZLIB_1_2_9
25eec2b
+#endif
25eec2b
+
25eec2b
 #ifdef USE_PPPORT_H
25eec2b
 #  define NEED_sv_2pvbyte
25eec2b
 #  define NEED_sv_2pv_nolen
25eec2b
@@ -134,12 +138,13 @@ typedef struct di_stream {
25eec2b
     uLong    dict_adler ;
25eec2b
     int      last_error ;
25eec2b
     bool     zip_mode ;
25eec2b
-#define SETP_BYTE
25eec2b
+/* #define SETP_BYTE */
25eec2b
 #ifdef SETP_BYTE
25eec2b
+    /* SETP_BYTE only works with zlib up to 1.2.8 */
25eec2b
     bool     deflateParams_out_valid ;
25eec2b
     Bytef    deflateParams_out_byte;
25eec2b
 #else
25eec2b
-#define deflateParams_BUFFER_SIZE       0x4000
25eec2b
+#define deflateParams_BUFFER_SIZE       0x40000
25eec2b
     uLong    deflateParams_out_length;
25eec2b
     Bytef*   deflateParams_out_buffer;
25eec2b
 #endif
25eec2b
@@ -636,6 +641,103 @@ char * string ;
25eec2b
     return sv ;
25eec2b
 }
25eec2b
 
25eec2b
+#if 0
25eec2b
+int
25eec2b
+flushToBuffer(di_stream* s, int flush)
25eec2b
+{
25eec2b
+    dTHX;
25eec2b
+    int ret ;
25eec2b
+    z_stream * strm = &s->stream;
25eec2b
+
25eec2b
+    Bytef* output = s->deflateParams_out_buffer ;
25eec2b
+
25eec2b
+    strm->next_in = NULL;
25eec2b
+    strm->avail_in = 0;
25eec2b
+    
25eec2b
+    uLong total_output = 0;
25eec2b
+    uLong have = 0;
25eec2b
+
25eec2b
+    do 
25eec2b
+    {
25eec2b
+        if (output)
25eec2b
+            output = (unsigned char *)saferealloc(output, total_output + s->bufsize);
25eec2b
+        else
25eec2b
+            output = (unsigned char *)safemalloc(s->bufsize);
25eec2b
+
25eec2b
+        strm->next_out  = output + total_output;
25eec2b
+        strm->avail_out = s->bufsize;
25eec2b
+
25eec2b
+        ret = deflate(strm, flush);    /* no bad return value */
25eec2b
+        //assert(ret != Z_STREAM_ERROR);  /* state not clobbered */
25eec2b
+        if(ret == Z_STREAM_ERROR)
25eec2b
+        {
25eec2b
+            safefree(output);
25eec2b
+            return ret;
25eec2b
+        }
25eec2b
+        have = s->bufsize - strm->avail_out;
25eec2b
+        total_output += have;
25eec2b
+
25eec2b
+        //fprintf(stderr, "FLUSH %s %d, return %d\n", flush_flags[flush], have, ret);
25eec2b
+
25eec2b
+    } while (strm->avail_out == 0);
25eec2b
+
25eec2b
+    s->deflateParams_out_buffer = output;
25eec2b
+    s->deflateParams_out_length = total_output; 
25eec2b
+
25eec2b
+    return Z_OK;
25eec2b
+}
25eec2b
+#endif
25eec2b
+
25eec2b
+#ifndef SETP_BYTE
25eec2b
+int
25eec2b
+flushParams(di_stream* s)
25eec2b
+{
25eec2b
+    dTHX;
25eec2b
+    int ret ;
25eec2b
+    z_stream * strm = &s->stream;
25eec2b
+
25eec2b
+    strm->next_in = NULL;
25eec2b
+    strm->avail_in = 0;
25eec2b
+    
25eec2b
+    Bytef* output = s->deflateParams_out_buffer ;
25eec2b
+    uLong total_output = s->deflateParams_out_length;
25eec2b
+
25eec2b
+    uLong have = 0;
25eec2b
+
25eec2b
+    do 
25eec2b
+    {
25eec2b
+        if (output)
25eec2b
+            output = (unsigned char *)saferealloc(output, total_output + s->bufsize);
25eec2b
+        else
25eec2b
+            output = (unsigned char *)safemalloc(s->bufsize);
25eec2b
+
25eec2b
+        strm->next_out  = output + total_output;
25eec2b
+        strm->avail_out = s->bufsize;
25eec2b
+
25eec2b
+        ret = deflateParams(&(s->stream), s->Level, s->Strategy);
25eec2b
+        /* fprintf(stderr, "deflateParams %d %s %lu\n", ret,
25eec2b
+            GetErrorString(ret),  s->bufsize - strm->avail_out); */
25eec2b
+
25eec2b
+        if (ret == Z_STREAM_ERROR) 
25eec2b
+            break;
25eec2b
+
25eec2b
+        have = s->bufsize - strm->avail_out;
25eec2b
+        total_output += have;
25eec2b
+
25eec2b
+
25eec2b
+    } while (ret == Z_BUF_ERROR) ;
25eec2b
+
25eec2b
+    if(ret == Z_STREAM_ERROR)
25eec2b
+        safefree(output);
25eec2b
+    else 
25eec2b
+    {
25eec2b
+        s->deflateParams_out_buffer = output;
25eec2b
+        s->deflateParams_out_length = total_output; 
25eec2b
+    }
25eec2b
+
25eec2b
+    return ret;
25eec2b
+}
25eec2b
+#endif /* ! SETP_BYTE */
25eec2b
 
25eec2b
 #include "constants.h"
25eec2b
 
25eec2b
@@ -991,20 +1093,24 @@ deflate (s, buf, output)
25eec2b
     /* Check for saved output from deflateParams */
25eec2b
     if (s->deflateParams_out_length) {
25eec2b
         uLong plen = s->deflateParams_out_length ;
25eec2b
-        /* printf("Copy %d bytes saved data\n", plen);*/
25eec2b
+        /* printf("Copy %lu bytes saved data\n", plen); */
25eec2b
         if (s->stream.avail_out < plen) {
25eec2b
-            /*printf("GROW from %d to %d\n", s->stream.avail_out,
25eec2b
-                        SvLEN(output) + plen - s->stream.avail_out); */
25eec2b
-            Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
25eec2b
+            /* printf("GROW from %d to %lu\n", s->stream.avail_out,
25eec2b
+                        SvLEN(output) + plen - s->stream.avail_out);  */
25eec2b
+             s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
25eec2b
+             s->stream.next_out += cur_length;
25eec2b
         }
25eec2b
         
25eec2b
-        Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;	
25eec2b
-        cur_length = cur_length + plen;
25eec2b
+        Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ;	
25eec2b
+        cur_length += plen;
25eec2b
         SvCUR_set(output, cur_length);
25eec2b
-	s->stream.next_out += plen ;
25eec2b
-	s->stream.avail_out = SvLEN(output) - cur_length ;
25eec2b
-	increment = s->stream.avail_out;
25eec2b
-	s->deflateParams_out_length = 0;
25eec2b
+        s->stream.next_out += plen ;
25eec2b
+        s->stream.avail_out = SvLEN(output) - cur_length ;
25eec2b
+        increment = s->stream.avail_out;
25eec2b
+
25eec2b
+        s->deflateParams_out_length = 0;
25eec2b
+        Safefree(s->deflateParams_out_buffer);
25eec2b
+        s->deflateParams_out_buffer = NULL;
25eec2b
     }
25eec2b
 #endif
25eec2b
     RETVAL = Z_OK ;
25eec2b
@@ -1027,6 +1133,12 @@ deflate (s, buf, output)
25eec2b
         }
25eec2b
 
25eec2b
         RETVAL = deflate(&(s->stream), Z_NO_FLUSH);
25eec2b
+        if (RETVAL != Z_STREAM_ERROR) {
25eec2b
+            int done = increment -  s->stream.avail_out ;
25eec2b
+            /* printf("std DEFLATEr returned %d '%s'  avail in %d, out %d wrote %d\n", RETVAL,
25eec2b
+            GetErrorString(RETVAL), s->stream.avail_in,
25eec2b
+s->stream.avail_out, done); */
25eec2b
+        }
25eec2b
     
25eec2b
         if (trace) {
25eec2b
             printf("DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
25eec2b
@@ -1080,7 +1192,6 @@ flush(s, output, f=Z_FINISH)
25eec2b
   CODE:
25eec2b
     bufinc = s->bufsize;
25eec2b
   
25eec2b
-    s->stream.avail_in = 0; /* should be zero already anyway */
25eec2b
   
25eec2b
     /* retrieve the output buffer */
25eec2b
     output = deRef_l(output, "flush") ;
25eec2b
@@ -1108,20 +1219,24 @@ flush(s, output, f=Z_FINISH)
25eec2b
     /* Check for saved output from deflateParams */
25eec2b
     if (s->deflateParams_out_length) {
25eec2b
         uLong plen = s->deflateParams_out_length ;
25eec2b
-        /* printf("Copy %d bytes saved data\n", plen); */
25eec2b
+        /* printf("Copy %lu bytes saved data\n", plen); */
25eec2b
         if (s->stream.avail_out < plen) {
25eec2b
-            /* printf("GROW from %d to %d\n", s->stream.avail_out, 
25eec2b
+            /* printf("GROW from %d to %lu\n", s->stream.avail_out, 
25eec2b
                         SvLEN(output) + plen - s->stream.avail_out); */
25eec2b
-            Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
25eec2b
+            s->stream.next_out = (Bytef*) Sv_Grow(output, SvLEN(output) + plen - s->stream.avail_out) ;
25eec2b
+            s->stream.next_out += cur_length;
25eec2b
         }
25eec2b
         
25eec2b
-        Copy(s->stream.next_out, s->deflateParams_out_buffer, plen, Bytef) ;	
25eec2b
-        cur_length = cur_length + plen;
25eec2b
+        Copy(s->deflateParams_out_buffer, s->stream.next_out, plen, Bytef) ;	
25eec2b
+        cur_length += plen;
25eec2b
         SvCUR_set(output, cur_length);
25eec2b
-	s->stream.next_out += plen ;
25eec2b
-	s->stream.avail_out = SvLEN(output) - cur_length ;
25eec2b
-	increment = s->stream.avail_out;
25eec2b
-	s->deflateParams_out_length = 0;
25eec2b
+        s->stream.next_out += plen ;
25eec2b
+        s->stream.avail_out = SvLEN(output) - cur_length ;
25eec2b
+        increment = s->stream.avail_out;
25eec2b
+
25eec2b
+        s->deflateParams_out_length = 0;
25eec2b
+        Safefree(s->deflateParams_out_buffer);
25eec2b
+        s->deflateParams_out_buffer = NULL;
25eec2b
     }
25eec2b
 #endif
25eec2b
 
25eec2b
@@ -1145,9 +1260,15 @@ flush(s, output, f=Z_FINISH)
25eec2b
         }
25eec2b
 
25eec2b
         RETVAL = deflate(&(s->stream), f);
25eec2b
+        if (RETVAL != Z_STREAM_ERROR) {
25eec2b
+            int done = availableout -  s->stream.avail_out ;
25eec2b
+            /* printf("flush DEFLATEr returned %d '%s'  avail in %d, out %d wrote %d\n", RETVAL,
25eec2b
+            GetErrorString(RETVAL), s->stream.avail_in,
25eec2b
+s->stream.avail_out, done); */
25eec2b
+        }
25eec2b
     
25eec2b
         if (trace) {
25eec2b
-            printf("flush DEFLATE returned %d %s, avail in %d, out %d\n", RETVAL,
25eec2b
+            printf("flush DEFLATE returned %d '%s', avail in %d, out %d\n", RETVAL,
25eec2b
             GetErrorString(RETVAL), s->stream.avail_in, s->stream.avail_out); 
25eec2b
             DispStream(s, "AFTER");
25eec2b
         }
25eec2b
@@ -1184,41 +1305,38 @@ _deflateParams(s, flags, level, strategy, bufsize)
25eec2b
 	int	level
25eec2b
 	int	strategy
25eec2b
     	uLong	bufsize
25eec2b
+	bool changed = FALSE;
25eec2b
     CODE:
25eec2b
-	/* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize); 
25eec2b
-	printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
25eec2b
-	if (flags & 1)
25eec2b
-	    s->Level = level ;
25eec2b
-	if (flags & 2)
25eec2b
-	    s->Strategy = strategy ;
25eec2b
-        if (flags & 4) {
25eec2b
+        /* printf("_deflateParams(Flags %d Level %d Strategy %d Bufsize %d)\n", flags, level, strategy, bufsize); 
25eec2b
+        printf("Before -- Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize); */
25eec2b
+        if (flags & 1 && level != s->Level) {
25eec2b
+            s->Level = level ;
25eec2b
+            changed = TRUE;
25eec2b
+        }
25eec2b
+        if (flags & 2 && strategy != s->Strategy) {
25eec2b
+            s->Strategy = strategy ;
25eec2b
+            changed = TRUE;
25eec2b
+        }
25eec2b
+        if (flags & 4)
25eec2b
             s->bufsize = bufsize; 
25eec2b
-	}
25eec2b
-	/* printf("After --  Level %d, Strategy %d, Bufsize %d\n", s->Level, s->Strategy, s->bufsize);*/
25eec2b
+        if (changed) {
25eec2b
 #ifdef SETP_BYTE
25eec2b
-        s->stream.avail_in = 0; 
25eec2b
-        s->stream.next_out = &(s->deflateParams_out_byte) ;
25eec2b
-        s->stream.avail_out = 1;
25eec2b
-	RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
25eec2b
-	s->deflateParams_out_valid = 
25eec2b
-		(RETVAL == Z_OK && s->stream.avail_out == 0) ;
25eec2b
-	/* printf("RETVAL %d, avail out %d, byte %c\n", RETVAL, s->stream.avail_out, s->deflateParams_out_byte); */
25eec2b
+            s->stream.avail_in = 0; 
25eec2b
+            s->stream.next_out = &(s->deflateParams_out_byte) ;
25eec2b
+            s->stream.avail_out = 1;
25eec2b
+            RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
25eec2b
+            s->deflateParams_out_valid = 
25eec2b
+            (RETVAL == Z_OK && s->stream.avail_out == 0) ;
25eec2b
 #else
25eec2b
-	/* printf("Level %d Strategy %d, Prev Len %d\n", 
25eec2b
+            /* printf("Level %d Strategy %d, Prev Len %d\n", 
25eec2b
                 s->Level, s->Strategy, s->deflateParams_out_length); */
25eec2b
-        s->stream.avail_in = 0; 
25eec2b
-        if (s->deflateParams_out_buffer == NULL)
25eec2b
-            s->deflateParams_out_buffer = safemalloc(deflateParams_BUFFER_SIZE);
25eec2b
-        s->stream.next_out = s->deflateParams_out_buffer ;
25eec2b
-        s->stream.avail_out = deflateParams_BUFFER_SIZE;
25eec2b
-
25eec2b
-	RETVAL = deflateParams(&(s->stream), s->Level, s->Strategy);
25eec2b
-	s->deflateParams_out_length = deflateParams_BUFFER_SIZE - s->stream.avail_out;
25eec2b
-	/* printf("RETVAL %d, length out %d, avail %d\n", 
25eec2b
-                    RETVAL, s->deflateParams_out_length, s->stream.avail_out ); */
25eec2b
+            RETVAL = flushParams(s);
25eec2b
 #endif
25eec2b
+        }
25eec2b
+        else
25eec2b
+            RETVAL = Z_OK;
25eec2b
     OUTPUT:
25eec2b
-	RETVAL
25eec2b
+        RETVAL
25eec2b
 
25eec2b
 
25eec2b
 int
25eec2b
diff --git a/t/02zlib.t b/t/02zlib.t
25eec2b
index 2c9aad6..5d024a9 100644
25eec2b
--- a/t/02zlib.t
25eec2b
+++ b/t/02zlib.t
25eec2b
@@ -27,7 +27,7 @@ BEGIN
25eec2b
         $count = 232 ;
25eec2b
     }
25eec2b
     elsif ($] >= 5.006) {
25eec2b
-        $count = 317 ;
25eec2b
+        $count = 320 ;
25eec2b
     }
25eec2b
     else {
25eec2b
         $count = 275 ;
25eec2b
@@ -559,6 +559,13 @@ SKIP:
25eec2b
     is $x->get_Level(),    Z_BEST_SPEED;
25eec2b
     is $x->get_Strategy(), Z_HUFFMAN_ONLY;
25eec2b
      
25eec2b
+    # change both Level & Strategy again without any calls to deflate 
25eec2b
+    $status = $x->deflateParams(-Level => Z_DEFAULT_COMPRESSION, -Strategy => Z_DEFAULT_STRATEGY, -Bufsize => 1234) ;
25eec2b
+    cmp_ok $status, '==', Z_OK ;
25eec2b
+    
25eec2b
+    is $x->get_Level(),    Z_DEFAULT_COMPRESSION;
25eec2b
+    is $x->get_Strategy(), Z_DEFAULT_STRATEGY;
25eec2b
+     
25eec2b
     $status = $x->deflate($goodbye, $Answer) ;
25eec2b
     cmp_ok $status, '==', Z_OK ;
25eec2b
     $input .= $goodbye;
25eec2b
@@ -568,7 +575,7 @@ SKIP:
25eec2b
     cmp_ok $status, '==', Z_OK ;
25eec2b
     
25eec2b
     is $x->get_Level(),    Z_NO_COMPRESSION;
25eec2b
-    is $x->get_Strategy(), Z_HUFFMAN_ONLY;
25eec2b
+    is $x->get_Strategy(), Z_DEFAULT_STRATEGY;
25eec2b
      
25eec2b
     $status = $x->deflate($goodbye, $Answer) ;
25eec2b
     cmp_ok $status, '==', Z_OK ;
25eec2b
-- 
25eec2b
2.7.4
25eec2b