LCOV - code coverage report
Current view: top level - third_party/openssl/crypto/comp - c_zlib.c (source / functions) Hit Total Coverage
Test: tmp.zDYK9MVh93 Lines: 2 4 50.0 %
Date: 2015-10-10 Functions: 1 2 50.0 %

          Line data    Source code
       1             : #include <stdio.h>
       2             : #include <stdlib.h>
       3             : #include <string.h>
       4             : #include <openssl/objects.h>
       5             : #include <openssl/comp.h>
       6             : #include <openssl/err.h>
       7             : 
       8             : COMP_METHOD *COMP_zlib(void);
       9             : 
      10             : static COMP_METHOD zlib_method_nozlib = {
      11             :     NID_undef,
      12             :     "(undef)",
      13             :     NULL,
      14             :     NULL,
      15             :     NULL,
      16             :     NULL,
      17             :     NULL,
      18             :     NULL,
      19             : };
      20             : 
      21             : #ifndef ZLIB
      22             : # undef ZLIB_SHARED
      23             : #else
      24             : 
      25             : # include <zlib.h>
      26             : 
      27             : static int zlib_stateful_init(COMP_CTX *ctx);
      28             : static void zlib_stateful_finish(COMP_CTX *ctx);
      29             : static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
      30             :                                         unsigned int olen, unsigned char *in,
      31             :                                         unsigned int ilen);
      32             : static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
      33             :                                       unsigned int olen, unsigned char *in,
      34             :                                       unsigned int ilen);
      35             : 
      36             : /* memory allocations functions for zlib intialization */
      37             : static void *zlib_zalloc(void *opaque, unsigned int no, unsigned int size)
      38             : {
      39             :     void *p;
      40             : 
      41             :     p = OPENSSL_malloc(no * size);
      42             :     if (p)
      43             :         memset(p, 0, no * size);
      44             :     return p;
      45             : }
      46             : 
      47             : static void zlib_zfree(void *opaque, void *address)
      48             : {
      49             :     OPENSSL_free(address);
      50             : }
      51             : 
      52             : # if 0
      53             : static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
      54             :                                unsigned int olen, unsigned char *in,
      55             :                                unsigned int ilen);
      56             : static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
      57             :                              unsigned int olen, unsigned char *in,
      58             :                              unsigned int ilen);
      59             : 
      60             : static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source,
      61             :                          uLong sourceLen);
      62             : 
      63             : static COMP_METHOD zlib_stateless_method = {
      64             :     NID_zlib_compression,
      65             :     LN_zlib_compression,
      66             :     NULL,
      67             :     NULL,
      68             :     zlib_compress_block,
      69             :     zlib_expand_block,
      70             :     NULL,
      71             :     NULL,
      72             : };
      73             : # endif
      74             : 
      75             : static COMP_METHOD zlib_stateful_method = {
      76             :     NID_zlib_compression,
      77             :     LN_zlib_compression,
      78             :     zlib_stateful_init,
      79             :     zlib_stateful_finish,
      80             :     zlib_stateful_compress_block,
      81             :     zlib_stateful_expand_block,
      82             :     NULL,
      83             :     NULL,
      84             : };
      85             : 
      86             : /*
      87             :  * When OpenSSL is built on Windows, we do not want to require that
      88             :  * the ZLIB.DLL be available in order for the OpenSSL DLLs to
      89             :  * work.  Therefore, all ZLIB routines are loaded at run time
      90             :  * and we do not link to a .LIB file when ZLIB_SHARED is set.
      91             :  */
      92             : # if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
      93             : #  include <windows.h>
      94             : # endif                         /* !(OPENSSL_SYS_WINDOWS ||
      95             :                                  * OPENSSL_SYS_WIN32) */
      96             : 
      97             : # ifdef ZLIB_SHARED
      98             : #  include <openssl/dso.h>
      99             : 
     100             : /* Function pointers */
     101             : typedef int (*compress_ft) (Bytef *dest, uLongf * destLen,
     102             :                             const Bytef *source, uLong sourceLen);
     103             : typedef int (*inflateEnd_ft) (z_streamp strm);
     104             : typedef int (*inflate_ft) (z_streamp strm, int flush);
     105             : typedef int (*inflateInit__ft) (z_streamp strm,
     106             :                                 const char *version, int stream_size);
     107             : typedef int (*deflateEnd_ft) (z_streamp strm);
     108             : typedef int (*deflate_ft) (z_streamp strm, int flush);
     109             : typedef int (*deflateInit__ft) (z_streamp strm, int level,
     110             :                                 const char *version, int stream_size);
     111             : typedef const char *(*zError__ft) (int err);
     112             : static compress_ft p_compress = NULL;
     113             : static inflateEnd_ft p_inflateEnd = NULL;
     114             : static inflate_ft p_inflate = NULL;
     115             : static inflateInit__ft p_inflateInit_ = NULL;
     116             : static deflateEnd_ft p_deflateEnd = NULL;
     117             : static deflate_ft p_deflate = NULL;
     118             : static deflateInit__ft p_deflateInit_ = NULL;
     119             : static zError__ft p_zError = NULL;
     120             : 
     121             : static int zlib_loaded = 0;     /* only attempt to init func pts once */
     122             : static DSO *zlib_dso = NULL;
     123             : 
     124             : #  define compress                p_compress
     125             : #  define inflateEnd              p_inflateEnd
     126             : #  define inflate                 p_inflate
     127             : #  define inflateInit_            p_inflateInit_
     128             : #  define deflateEnd              p_deflateEnd
     129             : #  define deflate                 p_deflate
     130             : #  define deflateInit_            p_deflateInit_
     131             : #  define zError                  p_zError
     132             : # endif                         /* ZLIB_SHARED */
     133             : 
     134             : struct zlib_state {
     135             :     z_stream istream;
     136             :     z_stream ostream;
     137             : };
     138             : 
     139             : static int zlib_stateful_ex_idx = -1;
     140             : 
     141             : static int zlib_stateful_init(COMP_CTX *ctx)
     142             : {
     143             :     int err;
     144             :     struct zlib_state *state =
     145             :         (struct zlib_state *)OPENSSL_malloc(sizeof(struct zlib_state));
     146             : 
     147             :     if (state == NULL)
     148             :         goto err;
     149             : 
     150             :     state->istream.zalloc = zlib_zalloc;
     151             :     state->istream.zfree = zlib_zfree;
     152             :     state->istream.opaque = Z_NULL;
     153             :     state->istream.next_in = Z_NULL;
     154             :     state->istream.next_out = Z_NULL;
     155             :     state->istream.avail_in = 0;
     156             :     state->istream.avail_out = 0;
     157             :     err = inflateInit_(&state->istream, ZLIB_VERSION, sizeof(z_stream));
     158             :     if (err != Z_OK)
     159             :         goto err;
     160             : 
     161             :     state->ostream.zalloc = zlib_zalloc;
     162             :     state->ostream.zfree = zlib_zfree;
     163             :     state->ostream.opaque = Z_NULL;
     164             :     state->ostream.next_in = Z_NULL;
     165             :     state->ostream.next_out = Z_NULL;
     166             :     state->ostream.avail_in = 0;
     167             :     state->ostream.avail_out = 0;
     168             :     err = deflateInit_(&state->ostream, Z_DEFAULT_COMPRESSION,
     169             :                        ZLIB_VERSION, sizeof(z_stream));
     170             :     if (err != Z_OK)
     171             :         goto err;
     172             : 
     173             :     CRYPTO_new_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
     174             :     CRYPTO_set_ex_data(&ctx->ex_data, zlib_stateful_ex_idx, state);
     175             :     return 1;
     176             :  err:
     177             :     if (state)
     178             :         OPENSSL_free(state);
     179             :     return 0;
     180             : }
     181             : 
     182             : static void zlib_stateful_finish(COMP_CTX *ctx)
     183             : {
     184             :     struct zlib_state *state =
     185             :         (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
     186             :                                                 zlib_stateful_ex_idx);
     187             :     inflateEnd(&state->istream);
     188             :     deflateEnd(&state->ostream);
     189             :     OPENSSL_free(state);
     190             :     CRYPTO_free_ex_data(CRYPTO_EX_INDEX_COMP, ctx, &ctx->ex_data);
     191             : }
     192             : 
     193             : static int zlib_stateful_compress_block(COMP_CTX *ctx, unsigned char *out,
     194             :                                         unsigned int olen, unsigned char *in,
     195             :                                         unsigned int ilen)
     196             : {
     197             :     int err = Z_OK;
     198             :     struct zlib_state *state =
     199             :         (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
     200             :                                                 zlib_stateful_ex_idx);
     201             : 
     202             :     if (state == NULL)
     203             :         return -1;
     204             : 
     205             :     state->ostream.next_in = in;
     206             :     state->ostream.avail_in = ilen;
     207             :     state->ostream.next_out = out;
     208             :     state->ostream.avail_out = olen;
     209             :     if (ilen > 0)
     210             :         err = deflate(&state->ostream, Z_SYNC_FLUSH);
     211             :     if (err != Z_OK)
     212             :         return -1;
     213             : # ifdef DEBUG_ZLIB
     214             :     fprintf(stderr, "compress(%4d)->%4d %s\n",
     215             :             ilen, olen - state->ostream.avail_out,
     216             :             (ilen != olen - state->ostream.avail_out) ? "zlib" : "clear");
     217             : # endif
     218             :     return olen - state->ostream.avail_out;
     219             : }
     220             : 
     221             : static int zlib_stateful_expand_block(COMP_CTX *ctx, unsigned char *out,
     222             :                                       unsigned int olen, unsigned char *in,
     223             :                                       unsigned int ilen)
     224             : {
     225             :     int err = Z_OK;
     226             : 
     227             :     struct zlib_state *state =
     228             :         (struct zlib_state *)CRYPTO_get_ex_data(&ctx->ex_data,
     229             :                                                 zlib_stateful_ex_idx);
     230             : 
     231             :     if (state == NULL)
     232             :         return 0;
     233             : 
     234             :     state->istream.next_in = in;
     235             :     state->istream.avail_in = ilen;
     236             :     state->istream.next_out = out;
     237             :     state->istream.avail_out = olen;
     238             :     if (ilen > 0)
     239             :         err = inflate(&state->istream, Z_SYNC_FLUSH);
     240             :     if (err != Z_OK)
     241             :         return -1;
     242             : # ifdef DEBUG_ZLIB
     243             :     fprintf(stderr, "expand(%4d)->%4d %s\n",
     244             :             ilen, olen - state->istream.avail_out,
     245             :             (ilen != olen - state->istream.avail_out) ? "zlib" : "clear");
     246             : # endif
     247             :     return olen - state->istream.avail_out;
     248             : }
     249             : 
     250             : # if 0
     251             : static int zlib_compress_block(COMP_CTX *ctx, unsigned char *out,
     252             :                                unsigned int olen, unsigned char *in,
     253             :                                unsigned int ilen)
     254             : {
     255             :     unsigned long l;
     256             :     int i;
     257             :     int clear = 1;
     258             : 
     259             :     if (ilen > 128) {
     260             :         out[0] = 1;
     261             :         l = olen - 1;
     262             :         i = compress(&(out[1]), &l, in, (unsigned long)ilen);
     263             :         if (i != Z_OK)
     264             :             return (-1);
     265             :         if (ilen > l) {
     266             :             clear = 0;
     267             :             l++;
     268             :         }
     269             :     }
     270             :     if (clear) {
     271             :         out[0] = 0;
     272             :         memcpy(&(out[1]), in, ilen);
     273             :         l = ilen + 1;
     274             :     }
     275             : #  ifdef DEBUG_ZLIB
     276             :     fprintf(stderr, "compress(%4d)->%4d %s\n",
     277             :             ilen, (int)l, (clear) ? "clear" : "zlib");
     278             : #  endif
     279             :     return ((int)l);
     280             : }
     281             : 
     282             : static int zlib_expand_block(COMP_CTX *ctx, unsigned char *out,
     283             :                              unsigned int olen, unsigned char *in,
     284             :                              unsigned int ilen)
     285             : {
     286             :     unsigned long l;
     287             :     int i;
     288             : 
     289             :     if (in[0]) {
     290             :         l = olen;
     291             :         i = zz_uncompress(out, &l, &(in[1]), (unsigned long)ilen - 1);
     292             :         if (i != Z_OK)
     293             :             return (-1);
     294             :     } else {
     295             :         memcpy(out, &(in[1]), ilen - 1);
     296             :         l = ilen - 1;
     297             :     }
     298             : #  ifdef DEBUG_ZLIB
     299             :     fprintf(stderr, "expand  (%4d)->%4d %s\n",
     300             :             ilen, (int)l, in[0] ? "zlib" : "clear");
     301             : #  endif
     302             :     return ((int)l);
     303             : }
     304             : 
     305             : static int zz_uncompress(Bytef *dest, uLongf * destLen, const Bytef *source,
     306             :                          uLong sourceLen)
     307             : {
     308             :     z_stream stream;
     309             :     int err;
     310             : 
     311             :     stream.next_in = (Bytef *)source;
     312             :     stream.avail_in = (uInt) sourceLen;
     313             :     /* Check for source > 64K on 16-bit machine: */
     314             :     if ((uLong) stream.avail_in != sourceLen)
     315             :         return Z_BUF_ERROR;
     316             : 
     317             :     stream.next_out = dest;
     318             :     stream.avail_out = (uInt) * destLen;
     319             :     if ((uLong) stream.avail_out != *destLen)
     320             :         return Z_BUF_ERROR;
     321             : 
     322             :     stream.zalloc = (alloc_func) 0;
     323             :     stream.zfree = (free_func) 0;
     324             : 
     325             :     err = inflateInit_(&stream, ZLIB_VERSION, sizeof(z_stream));
     326             :     if (err != Z_OK)
     327             :         return err;
     328             : 
     329             :     err = inflate(&stream, Z_FINISH);
     330             :     if (err != Z_STREAM_END) {
     331             :         inflateEnd(&stream);
     332             :         return err;
     333             :     }
     334             :     *destLen = stream.total_out;
     335             : 
     336             :     err = inflateEnd(&stream);
     337             :     return err;
     338             : }
     339             : # endif
     340             : 
     341             : #endif
     342             : 
     343         121 : COMP_METHOD *COMP_zlib(void)
     344             : {
     345             :     COMP_METHOD *meth = &zlib_method_nozlib;
     346             : 
     347             : #ifdef ZLIB_SHARED
     348             :     if (!zlib_loaded) {
     349             : # if defined(OPENSSL_SYS_WINDOWS) || defined(OPENSSL_SYS_WIN32)
     350             :         zlib_dso = DSO_load(NULL, "ZLIB1", NULL, 0);
     351             : # else
     352             :         zlib_dso = DSO_load(NULL, "z", NULL, 0);
     353             : # endif
     354             :         if (zlib_dso != NULL) {
     355             :             p_compress = (compress_ft) DSO_bind_func(zlib_dso, "compress");
     356             :             p_inflateEnd
     357             :                 = (inflateEnd_ft) DSO_bind_func(zlib_dso, "inflateEnd");
     358             :             p_inflate = (inflate_ft) DSO_bind_func(zlib_dso, "inflate");
     359             :             p_inflateInit_
     360             :                 = (inflateInit__ft) DSO_bind_func(zlib_dso, "inflateInit_");
     361             :             p_deflateEnd
     362             :                 = (deflateEnd_ft) DSO_bind_func(zlib_dso, "deflateEnd");
     363             :             p_deflate = (deflate_ft) DSO_bind_func(zlib_dso, "deflate");
     364             :             p_deflateInit_
     365             :                 = (deflateInit__ft) DSO_bind_func(zlib_dso, "deflateInit_");
     366             :             p_zError = (zError__ft) DSO_bind_func(zlib_dso, "zError");
     367             : 
     368             :             if (p_compress && p_inflateEnd && p_inflate
     369             :                 && p_inflateInit_ && p_deflateEnd
     370             :                 && p_deflate && p_deflateInit_ && p_zError)
     371             :                 zlib_loaded++;
     372             :         }
     373             :     }
     374             : #endif
     375             : #ifdef ZLIB_SHARED
     376             :     if (zlib_loaded)
     377             : #endif
     378             : #if defined(ZLIB) || defined(ZLIB_SHARED)
     379             :     {
     380             :         /*
     381             :          * init zlib_stateful_ex_idx here so that in a multi-process
     382             :          * application it's enough to intialize openssl before forking (idx
     383             :          * will be inherited in all the children)
     384             :          */
     385             :         if (zlib_stateful_ex_idx == -1) {
     386             :             CRYPTO_w_lock(CRYPTO_LOCK_COMP);
     387             :             if (zlib_stateful_ex_idx == -1)
     388             :                 zlib_stateful_ex_idx =
     389             :                     CRYPTO_get_ex_new_index(CRYPTO_EX_INDEX_COMP,
     390             :                                             0, NULL, NULL, NULL, NULL);
     391             :             CRYPTO_w_unlock(CRYPTO_LOCK_COMP);
     392             :             if (zlib_stateful_ex_idx == -1)
     393             :                 goto err;
     394             :         }
     395             : 
     396             :         meth = &zlib_stateful_method;
     397             :     }
     398             :  err:
     399             : #endif
     400             : 
     401         121 :     return (meth);
     402             : }
     403             : 
     404           0 : void COMP_zlib_cleanup(void)
     405             : {
     406             : #ifdef ZLIB_SHARED
     407             :     if (zlib_dso)
     408             :         DSO_free(zlib_dso);
     409             : #endif
     410           0 : }
     411             : 
     412             : #ifdef ZLIB
     413             : 
     414             : /* Zlib based compression/decompression filter BIO */
     415             : 
     416             : typedef struct {
     417             :     unsigned char *ibuf;        /* Input buffer */
     418             :     int ibufsize;               /* Buffer size */
     419             :     z_stream zin;               /* Input decompress context */
     420             :     unsigned char *obuf;        /* Output buffer */
     421             :     int obufsize;               /* Output buffer size */
     422             :     unsigned char *optr;        /* Position in output buffer */
     423             :     int ocount;                 /* Amount of data in output buffer */
     424             :     int odone;                  /* deflate EOF */
     425             :     int comp_level;             /* Compression level to use */
     426             :     z_stream zout;              /* Output compression context */
     427             : } BIO_ZLIB_CTX;
     428             : 
     429             : # define ZLIB_DEFAULT_BUFSIZE 1024
     430             : 
     431             : static int bio_zlib_new(BIO *bi);
     432             : static int bio_zlib_free(BIO *bi);
     433             : static int bio_zlib_read(BIO *b, char *out, int outl);
     434             : static int bio_zlib_write(BIO *b, const char *in, int inl);
     435             : static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr);
     436             : static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp);
     437             : 
     438             : static BIO_METHOD bio_meth_zlib = {
     439             :     BIO_TYPE_COMP,
     440             :     "zlib",
     441             :     bio_zlib_write,
     442             :     bio_zlib_read,
     443             :     NULL,
     444             :     NULL,
     445             :     bio_zlib_ctrl,
     446             :     bio_zlib_new,
     447             :     bio_zlib_free,
     448             :     bio_zlib_callback_ctrl
     449             : };
     450             : 
     451             : BIO_METHOD *BIO_f_zlib(void)
     452             : {
     453             :     return &bio_meth_zlib;
     454             : }
     455             : 
     456             : static int bio_zlib_new(BIO *bi)
     457             : {
     458             :     BIO_ZLIB_CTX *ctx;
     459             : # ifdef ZLIB_SHARED
     460             :     (void)COMP_zlib();
     461             :     if (!zlib_loaded) {
     462             :         COMPerr(COMP_F_BIO_ZLIB_NEW, COMP_R_ZLIB_NOT_SUPPORTED);
     463             :         return 0;
     464             :     }
     465             : # endif
     466             :     ctx = OPENSSL_malloc(sizeof(BIO_ZLIB_CTX));
     467             :     if (!ctx) {
     468             :         COMPerr(COMP_F_BIO_ZLIB_NEW, ERR_R_MALLOC_FAILURE);
     469             :         return 0;
     470             :     }
     471             :     ctx->ibuf = NULL;
     472             :     ctx->obuf = NULL;
     473             :     ctx->ibufsize = ZLIB_DEFAULT_BUFSIZE;
     474             :     ctx->obufsize = ZLIB_DEFAULT_BUFSIZE;
     475             :     ctx->zin.zalloc = Z_NULL;
     476             :     ctx->zin.zfree = Z_NULL;
     477             :     ctx->zin.next_in = NULL;
     478             :     ctx->zin.avail_in = 0;
     479             :     ctx->zin.next_out = NULL;
     480             :     ctx->zin.avail_out = 0;
     481             :     ctx->zout.zalloc = Z_NULL;
     482             :     ctx->zout.zfree = Z_NULL;
     483             :     ctx->zout.next_in = NULL;
     484             :     ctx->zout.avail_in = 0;
     485             :     ctx->zout.next_out = NULL;
     486             :     ctx->zout.avail_out = 0;
     487             :     ctx->odone = 0;
     488             :     ctx->comp_level = Z_DEFAULT_COMPRESSION;
     489             :     bi->init = 1;
     490             :     bi->ptr = (char *)ctx;
     491             :     bi->flags = 0;
     492             :     return 1;
     493             : }
     494             : 
     495             : static int bio_zlib_free(BIO *bi)
     496             : {
     497             :     BIO_ZLIB_CTX *ctx;
     498             :     if (!bi)
     499             :         return 0;
     500             :     ctx = (BIO_ZLIB_CTX *) bi->ptr;
     501             :     if (ctx->ibuf) {
     502             :         /* Destroy decompress context */
     503             :         inflateEnd(&ctx->zin);
     504             :         OPENSSL_free(ctx->ibuf);
     505             :     }
     506             :     if (ctx->obuf) {
     507             :         /* Destroy compress context */
     508             :         deflateEnd(&ctx->zout);
     509             :         OPENSSL_free(ctx->obuf);
     510             :     }
     511             :     OPENSSL_free(ctx);
     512             :     bi->ptr = NULL;
     513             :     bi->init = 0;
     514             :     bi->flags = 0;
     515             :     return 1;
     516             : }
     517             : 
     518             : static int bio_zlib_read(BIO *b, char *out, int outl)
     519             : {
     520             :     BIO_ZLIB_CTX *ctx;
     521             :     int ret;
     522             :     z_stream *zin;
     523             :     if (!out || !outl)
     524             :         return 0;
     525             :     ctx = (BIO_ZLIB_CTX *) b->ptr;
     526             :     zin = &ctx->zin;
     527             :     BIO_clear_retry_flags(b);
     528             :     if (!ctx->ibuf) {
     529             :         ctx->ibuf = OPENSSL_malloc(ctx->ibufsize);
     530             :         if (!ctx->ibuf) {
     531             :             COMPerr(COMP_F_BIO_ZLIB_READ, ERR_R_MALLOC_FAILURE);
     532             :             return 0;
     533             :         }
     534             :         inflateInit(zin);
     535             :         zin->next_in = ctx->ibuf;
     536             :         zin->avail_in = 0;
     537             :     }
     538             : 
     539             :     /* Copy output data directly to supplied buffer */
     540             :     zin->next_out = (unsigned char *)out;
     541             :     zin->avail_out = (unsigned int)outl;
     542             :     for (;;) {
     543             :         /* Decompress while data available */
     544             :         while (zin->avail_in) {
     545             :             ret = inflate(zin, 0);
     546             :             if ((ret != Z_OK) && (ret != Z_STREAM_END)) {
     547             :                 COMPerr(COMP_F_BIO_ZLIB_READ, COMP_R_ZLIB_INFLATE_ERROR);
     548             :                 ERR_add_error_data(2, "zlib error:", zError(ret));
     549             :                 return 0;
     550             :             }
     551             :             /* If EOF or we've read everything then return */
     552             :             if ((ret == Z_STREAM_END) || !zin->avail_out)
     553             :                 return outl - zin->avail_out;
     554             :         }
     555             : 
     556             :         /*
     557             :          * No data in input buffer try to read some in, if an error then
     558             :          * return the total data read.
     559             :          */
     560             :         ret = BIO_read(b->next_bio, ctx->ibuf, ctx->ibufsize);
     561             :         if (ret <= 0) {
     562             :             /* Total data read */
     563             :             int tot = outl - zin->avail_out;
     564             :             BIO_copy_next_retry(b);
     565             :             if (ret < 0)
     566             :                 return (tot > 0) ? tot : ret;
     567             :             return tot;
     568             :         }
     569             :         zin->avail_in = ret;
     570             :         zin->next_in = ctx->ibuf;
     571             :     }
     572             : }
     573             : 
     574             : static int bio_zlib_write(BIO *b, const char *in, int inl)
     575             : {
     576             :     BIO_ZLIB_CTX *ctx;
     577             :     int ret;
     578             :     z_stream *zout;
     579             :     if (!in || !inl)
     580             :         return 0;
     581             :     ctx = (BIO_ZLIB_CTX *) b->ptr;
     582             :     if (ctx->odone)
     583             :         return 0;
     584             :     zout = &ctx->zout;
     585             :     BIO_clear_retry_flags(b);
     586             :     if (!ctx->obuf) {
     587             :         ctx->obuf = OPENSSL_malloc(ctx->obufsize);
     588             :         /* Need error here */
     589             :         if (!ctx->obuf) {
     590             :             COMPerr(COMP_F_BIO_ZLIB_WRITE, ERR_R_MALLOC_FAILURE);
     591             :             return 0;
     592             :         }
     593             :         ctx->optr = ctx->obuf;
     594             :         ctx->ocount = 0;
     595             :         deflateInit(zout, ctx->comp_level);
     596             :         zout->next_out = ctx->obuf;
     597             :         zout->avail_out = ctx->obufsize;
     598             :     }
     599             :     /* Obtain input data directly from supplied buffer */
     600             :     zout->next_in = (void *)in;
     601             :     zout->avail_in = inl;
     602             :     for (;;) {
     603             :         /* If data in output buffer write it first */
     604             :         while (ctx->ocount) {
     605             :             ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
     606             :             if (ret <= 0) {
     607             :                 /* Total data written */
     608             :                 int tot = inl - zout->avail_in;
     609             :                 BIO_copy_next_retry(b);
     610             :                 if (ret < 0)
     611             :                     return (tot > 0) ? tot : ret;
     612             :                 return tot;
     613             :             }
     614             :             ctx->optr += ret;
     615             :             ctx->ocount -= ret;
     616             :         }
     617             : 
     618             :         /* Have we consumed all supplied data? */
     619             :         if (!zout->avail_in)
     620             :             return inl;
     621             : 
     622             :         /* Compress some more */
     623             : 
     624             :         /* Reset buffer */
     625             :         ctx->optr = ctx->obuf;
     626             :         zout->next_out = ctx->obuf;
     627             :         zout->avail_out = ctx->obufsize;
     628             :         /* Compress some more */
     629             :         ret = deflate(zout, 0);
     630             :         if (ret != Z_OK) {
     631             :             COMPerr(COMP_F_BIO_ZLIB_WRITE, COMP_R_ZLIB_DEFLATE_ERROR);
     632             :             ERR_add_error_data(2, "zlib error:", zError(ret));
     633             :             return 0;
     634             :         }
     635             :         ctx->ocount = ctx->obufsize - zout->avail_out;
     636             :     }
     637             : }
     638             : 
     639             : static int bio_zlib_flush(BIO *b)
     640             : {
     641             :     BIO_ZLIB_CTX *ctx;
     642             :     int ret;
     643             :     z_stream *zout;
     644             :     ctx = (BIO_ZLIB_CTX *) b->ptr;
     645             :     /* If no data written or already flush show success */
     646             :     if (!ctx->obuf || (ctx->odone && !ctx->ocount))
     647             :         return 1;
     648             :     zout = &ctx->zout;
     649             :     BIO_clear_retry_flags(b);
     650             :     /* No more input data */
     651             :     zout->next_in = NULL;
     652             :     zout->avail_in = 0;
     653             :     for (;;) {
     654             :         /* If data in output buffer write it first */
     655             :         while (ctx->ocount) {
     656             :             ret = BIO_write(b->next_bio, ctx->optr, ctx->ocount);
     657             :             if (ret <= 0) {
     658             :                 BIO_copy_next_retry(b);
     659             :                 return ret;
     660             :             }
     661             :             ctx->optr += ret;
     662             :             ctx->ocount -= ret;
     663             :         }
     664             :         if (ctx->odone)
     665             :             return 1;
     666             : 
     667             :         /* Compress some more */
     668             : 
     669             :         /* Reset buffer */
     670             :         ctx->optr = ctx->obuf;
     671             :         zout->next_out = ctx->obuf;
     672             :         zout->avail_out = ctx->obufsize;
     673             :         /* Compress some more */
     674             :         ret = deflate(zout, Z_FINISH);
     675             :         if (ret == Z_STREAM_END)
     676             :             ctx->odone = 1;
     677             :         else if (ret != Z_OK) {
     678             :             COMPerr(COMP_F_BIO_ZLIB_FLUSH, COMP_R_ZLIB_DEFLATE_ERROR);
     679             :             ERR_add_error_data(2, "zlib error:", zError(ret));
     680             :             return 0;
     681             :         }
     682             :         ctx->ocount = ctx->obufsize - zout->avail_out;
     683             :     }
     684             : }
     685             : 
     686             : static long bio_zlib_ctrl(BIO *b, int cmd, long num, void *ptr)
     687             : {
     688             :     BIO_ZLIB_CTX *ctx;
     689             :     int ret, *ip;
     690             :     int ibs, obs;
     691             :     if (!b->next_bio)
     692             :         return 0;
     693             :     ctx = (BIO_ZLIB_CTX *) b->ptr;
     694             :     switch (cmd) {
     695             : 
     696             :     case BIO_CTRL_RESET:
     697             :         ctx->ocount = 0;
     698             :         ctx->odone = 0;
     699             :         ret = 1;
     700             :         break;
     701             : 
     702             :     case BIO_CTRL_FLUSH:
     703             :         ret = bio_zlib_flush(b);
     704             :         if (ret > 0)
     705             :             ret = BIO_flush(b->next_bio);
     706             :         break;
     707             : 
     708             :     case BIO_C_SET_BUFF_SIZE:
     709             :         ibs = -1;
     710             :         obs = -1;
     711             :         if (ptr != NULL) {
     712             :             ip = ptr;
     713             :             if (*ip == 0)
     714             :                 ibs = (int)num;
     715             :             else
     716             :                 obs = (int)num;
     717             :         } else {
     718             :             ibs = (int)num;
     719             :             obs = ibs;
     720             :         }
     721             : 
     722             :         if (ibs != -1) {
     723             :             if (ctx->ibuf) {
     724             :                 OPENSSL_free(ctx->ibuf);
     725             :                 ctx->ibuf = NULL;
     726             :             }
     727             :             ctx->ibufsize = ibs;
     728             :         }
     729             : 
     730             :         if (obs != -1) {
     731             :             if (ctx->obuf) {
     732             :                 OPENSSL_free(ctx->obuf);
     733             :                 ctx->obuf = NULL;
     734             :             }
     735             :             ctx->obufsize = obs;
     736             :         }
     737             :         ret = 1;
     738             :         break;
     739             : 
     740             :     case BIO_C_DO_STATE_MACHINE:
     741             :         BIO_clear_retry_flags(b);
     742             :         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
     743             :         BIO_copy_next_retry(b);
     744             :         break;
     745             : 
     746             :     default:
     747             :         ret = BIO_ctrl(b->next_bio, cmd, num, ptr);
     748             :         break;
     749             : 
     750             :     }
     751             : 
     752             :     return ret;
     753             : }
     754             : 
     755             : static long bio_zlib_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
     756             : {
     757             :     if (!b->next_bio)
     758             :         return 0;
     759             :     return BIO_callback_ctrl(b->next_bio, cmd, fp);
     760             : }
     761             : 
     762             : #endif

Generated by: LCOV version 1.10