adenilson / rpms / zlib

Forked from rpms/zlib 8 months ago
Clone

Blame SOURCES/zlib-1.2.11-IBM-DFLTCC-compression-level-switching-issues.patch

65fa5e
Subject: [PATCH] Fixed DFLTCC compression level switching issues
65fa5e
65fa5e
---
65fa5e
 configure                     |  4 +--
65fa5e
 contrib/s390/dfltcc.c         | 52 ++++++++++++++++++++++++++++++-----
65fa5e
 contrib/s390/dfltcc_deflate.h |  2 ++
65fa5e
 deflate.c                     | 12 ++++----
65fa5e
 test/infcover.c               |  2 +-
65fa5e
 5 files changed, 57 insertions(+), 15 deletions(-)
65fa5e
65fa5e
diff --git a/configure b/configure
65fa5e
index bfe4386..70ed86b 100755
65fa5e
--- a/configure
65fa5e
+++ b/configure
65fa5e
@@ -139,7 +139,7 @@ case "$1" in
65fa5e
     -w* | --warn) warn=1; shift ;;
65fa5e
     -d* | --debug) debug=1; shift ;;
65fa5e
     --dfltcc)
65fa5e
-	    CFLAGS="$CFLAGS -DDFLTCC"
65fa5e
+	    CFLAGS="$CFLAGS -DDFLTCC -DDFLTCC_LEVEL_MASK=0x7e"
65fa5e
       OBJC="$OBJC dfltcc.o"
65fa5e
 	    PIC_OBJC="$PIC_OBJC dfltcc.lo"
65fa5e
       shift
65fa5e
@@ -838,7 +838,7 @@ cat > $test.c << EOF
65fa5e
 #include <sys/sdt.h>
65fa5e
 int main() { return 0; }
65fa5e
 EOF
65fa5e
-if try ${CC} ${CFLAGS} $test.c; then
65fa5e
+ if try $CC -c $CFLAGS $test.c; then
65fa5e
     echo "Checking for sys/sdt.h ... Yes." | tee -a configure.log
65fa5e
     CFLAGS="$CFLAGS -DHAVE_SYS_SDT_H"
65fa5e
     SFLAGS="$SFLAGS -DHAVE_SYS_SDT_H"
65fa5e
diff --git a/contrib/s390/dfltcc.c b/contrib/s390/dfltcc.c
65fa5e
index d88a0d6..94a196f 100644
65fa5e
--- a/contrib/s390/dfltcc.c
65fa5e
+++ b/contrib/s390/dfltcc.c
65fa5e
@@ -350,8 +350,12 @@ int ZLIB_INTERNAL dfltcc_deflate(strm, flush, result)
65fa5e
     int soft_bcc;
65fa5e
     int no_flush;
65fa5e
 
65fa5e
-    if (!dfltcc_can_deflate(strm))
65fa5e
+    if (!dfltcc_can_deflate(strm)) {
65fa5e
+        /* Clear history. */
65fa5e
+        if (flush == Z_FULL_FLUSH)
65fa5e
+            param->hl = 0;
65fa5e
         return 0;
65fa5e
+    }
65fa5e
 
65fa5e
 again:
65fa5e
     masked_avail_in = 0;
65fa5e
@@ -376,7 +380,8 @@ again:
65fa5e
         /* Clear history. */
65fa5e
         if (flush == Z_FULL_FLUSH)
65fa5e
             param->hl = 0; 
65fa5e
-        *result = need_more;
65fa5e
+        /* Trigger block post-processing if necessary. */
65fa5e
+        *result = no_flush ? need_more : block_done;
65fa5e
         return 1;
65fa5e
     }
65fa5e
 
65fa5e
@@ -403,13 +408,18 @@ again:
65fa5e
             param->bcf = 0;
65fa5e
             dfltcc_state->block_threshold =
65fa5e
                 strm->total_in + dfltcc_state->block_size;
65fa5e
-            if (strm->avail_out == 0) {
65fa5e
-                *result = need_more;
65fa5e
-                return 1;
65fa5e
-            }
65fa5e
         }
65fa5e
     }
65fa5e
 
65fa5e
+    /* No space for compressed data. If we proceed, dfltcc_cmpr() will return
65fa5e
+     * DFLTCC_CC_OP1_TOO_SHORT without buffering header bits, but we will still
65fa5e
+     * set BCF=1, which is wrong. Avoid complications and return early.
65fa5e
+     */
65fa5e
+    if (strm->avail_out == 0) {
65fa5e
+        *result = need_more;
65fa5e
+        return 1;
65fa5e
+    }
65fa5e
+
65fa5e
     /* The caller gave us too much data. Pass only one block worth of
65fa5e
      * uncompressed data to DFLTCC and mask the rest, so that on the next
65fa5e
      * iteration we start a new block.
65fa5e
@@ -737,10 +747,15 @@ __attribute__((constructor)) local void init_globals(void)
65fa5e
      * compiling with -m31, gcc defaults to ESA mode, however, since the kernel
65fa5e
      * is 64-bit, it's always z/Architecture mode at runtime.
65fa5e
      */
65fa5e
-    __asm__ volatile(".machinemode push\n"
65fa5e
+     __asm__ volatile(
65fa5e
+#ifndef __clang__
65fa5e
+                     ".machinemode push\n"
65fa5e
                      ".machinemode zarch\n"
65fa5e
+#endif
65fa5e
                      "stfle %[facilities]\n"
65fa5e
+#ifndef __clang__
65fa5e
                      ".machinemode pop\n"
65fa5e
+#endif
65fa5e
                      : [facilities] "=Q" (cpu_facilities)
65fa5e
                      , [r0] "+r" (r0)
65fa5e
                      :
65fa5e
@@ -872,6 +887,28 @@ int ZLIB_INTERNAL dfltcc_deflate_params(strm, level, strategy, flush)
65fa5e
     return Z_OK; 
65fa5e
 }
65fa5e
 
65fa5e
+int ZLIB_INTERNAL dfltcc_deflate_done(strm, flush)
65fa5e
+    z_streamp strm;
65fa5e
+    int flush;
65fa5e
+{
65fa5e
+    deflate_state FAR *state = (deflate_state FAR *)strm->state;
65fa5e
+    struct dfltcc_state FAR *dfltcc_state = GET_DFLTCC_STATE(state);
65fa5e
+    struct dfltcc_param_v0 FAR *param = &dfltcc_state->param;
65fa5e
+
65fa5e
+    /* When deflate(Z_FULL_FLUSH) is called with small avail_out, it might
65fa5e
+     * close the block without resetting the compression state. Detect this
65fa5e
+     * situation and return that deflation is not done.
65fa5e
+     */
65fa5e
+    if (flush == Z_FULL_FLUSH && strm->avail_out == 0)
65fa5e
+        return 0;
65fa5e
+
65fa5e
+    /* Return that deflation is not done if DFLTCC is used and either it
65fa5e
+     * buffered some data (Continuation Flag is set), or has not written EOBS
65fa5e
+     * yet (Block-Continuation Flag is set).
65fa5e
+     */
65fa5e
+    return !dfltcc_can_deflate(strm) || (!param->cf && !param->bcf);
65fa5e
+}
65fa5e
+
65fa5e
 /*
65fa5e
    Preloading history.
65fa5e
 */
65fa5e
@@ -925,6 +962,7 @@ int ZLIB_INTERNAL dfltcc_deflate_set_dictionary(strm, dictionary, dict_length)
65fa5e
 
65fa5e
     append_history(param, state->window, dictionary, dict_length);
65fa5e
     state->strstart = 1; /* Add FDICT to zlib header */
65fa5e
+    state->block_start = state->strstart; /* Make deflate_stored happy */
65fa5e
     return Z_OK;
65fa5e
 }
65fa5e
 
65fa5e
diff --git a/contrib/s390/dfltcc_deflate.h b/contrib/s390/dfltcc_deflate.h
65fa5e
index de36784..914daa4 100644
65fa5e
--- a/contrib/s390/dfltcc_deflate.h
65fa5e
+++ b/contrib/s390/dfltcc_deflate.h
65fa5e
@@ -11,6 +11,7 @@ int ZLIB_INTERNAL dfltcc_deflate_params OF((z_streamp strm,
65fa5e
                                             int level,
65fa5e
                                             int strategy,
65fa5e
                                             int *flush)); 
65fa5e
+int ZLIB_INTERNAL dfltcc_deflate_done OF((z_streamp strm, int flush));
65fa5e
 int ZLIB_INTERNAL dfltcc_deflate_set_dictionary OF((z_streamp strm,
65fa5e
                                                     const Bytef *dictionary,
65fa5e
                                                     uInt dict_length));
65fa5e
@@ -41,6 +42,7 @@ int ZLIB_INTERNAL dfltcc_deflate_get_dictionary OF((z_streamp strm,
65fa5e
         if (err == Z_STREAM_ERROR) \
65fa5e
             return err; \
65fa5e
     } while (0)
65fa5e
+#define DEFLATE_DONE dfltcc_deflate_done
65fa5e
 #define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, source_len) \
65fa5e
     do { \
65fa5e
         if (dfltcc_can_deflate((strm))) \
65fa5e
diff --git a/deflate.c b/deflate.c
65fa5e
index d907a1b..085abbe 100644
65fa5e
--- a/deflate.c
65fa5e
+++ b/deflate.c
65fa5e
@@ -75,6 +75,7 @@ const char deflate_copyright[] =
65fa5e
 #define DEFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
65fa5e
 #define DEFLATE_RESET_KEEP_HOOK(strm) do {} while (0)
65fa5e
 #define DEFLATE_PARAMS_HOOK(strm, level, strategy, hook_flush) do {} while (0)
65fa5e
+#define DEFLATE_DONE(strm, flush) 1
65fa5e
 #define DEFLATE_BOUND_ADJUST_COMPLEN(strm, complen, sourceLen) do {} while (0)
65fa5e
 #define DEFLATE_NEED_CONSERVATIVE_BOUND(strm) 0
65fa5e
 #define DEFLATE_HOOK(strm, flush, bstate) 0
65fa5e
@@ -605,14 +606,15 @@ int ZEXPORT deflateParams(strm, level, strategy)
65fa5e
     DEFLATE_PARAMS_HOOK(strm, level, strategy, &hook_flush);
65fa5e
     func = configuration_table[s->level].func;
65fa5e
 
65fa5e
-    if ((strategy != s->strategy || func != configuration_table[level].func ||
65fa5e
-        hook_flush != Z_NO_FLUSH) && s->last_flush != -2) {
65fa5e
+    if (((strategy != s->strategy || func != configuration_table[level].func) &&
65fa5e
+        s->last_flush != -2) || hook_flush != Z_NO_FLUSH) {
65fa5e
         /* Flush the last buffer: */
65fa5e
-        int err = deflate(strm, RANK(hook_flush) > RANK(Z_BLOCK) ?
65fa5e
-                          hook_flush : Z_BLOCK); 
65fa5e
+        int flush = RANK(hook_flush) > RANK(Z_BLOCK) ? hook_flush : Z_BLOCK;
65fa5e
+        int err = deflate(strm, flush);
65fa5e
         if (err == Z_STREAM_ERROR)
65fa5e
             return err;
65fa5e
-        if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead)
65fa5e
+        if (strm->avail_in || (s->strstart - s->block_start) + s->lookahead ||
65fa5e
+            !DEFLATE_DONE(strm, flush))
65fa5e
             return Z_BUF_ERROR;
65fa5e
     }
65fa5e
     if (s->level != level) {
65fa5e
diff --git a/test/infcover.c b/test/infcover.c
65fa5e
index a34cd17..a208219 100644
65fa5e
--- a/test/infcover.c
65fa5e
+++ b/test/infcover.c
65fa5e
@@ -373,7 +373,7 @@ local void cover_support(void)
65fa5e
     mem_setup(&strm;;
65fa5e
     strm.avail_in = 0;
65fa5e
     strm.next_in = Z_NULL;
65fa5e
-    ret = inflateInit_(&strm, ZLIB_VERSION - 1, (int)sizeof(z_stream));
65fa5e
+    ret = inflateInit_(&strm, &ZLIB_VERSION[1], (int)sizeof(z_stream));
65fa5e
                                                 assert(ret == Z_VERSION_ERROR);
65fa5e
     mem_done(&strm, "wrong version");
65fa5e
 
65fa5e
-- 
65fa5e
2.26.0
65fa5e