LCOV - differential code coverage report
Current view: top level - contrib/pgcrypto - pgp-compress.c (source / functions) Coverage Total Hit UBC GNC CBC DCB
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 86.4 % 125 108 17 1 107 1
Current Date: 2024-04-14 14:21:10 Functions: 100.0 % 11 11 1 10
Baseline: 16@8cea358b128 Branches: 73.2 % 56 41 15 41
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 86.4 % 125 108 17 1 107
Function coverage date bins:
(240..) days: 100.0 % 11 11 1 10
Branch coverage date bins:
(240..) days: 73.2 % 56 41 15 41

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*
                                  2                 :                :  * pgp-compress.c
                                  3                 :                :  *    ZIP and ZLIB compression via zlib.
                                  4                 :                :  *
                                  5                 :                :  * Copyright (c) 2005 Marko Kreen
                                  6                 :                :  * All rights reserved.
                                  7                 :                :  *
                                  8                 :                :  * Redistribution and use in source and binary forms, with or without
                                  9                 :                :  * modification, are permitted provided that the following conditions
                                 10                 :                :  * are met:
                                 11                 :                :  * 1. Redistributions of source code must retain the above copyright
                                 12                 :                :  *    notice, this list of conditions and the following disclaimer.
                                 13                 :                :  * 2. Redistributions in binary form must reproduce the above copyright
                                 14                 :                :  *    notice, this list of conditions and the following disclaimer in the
                                 15                 :                :  *    documentation and/or other materials provided with the distribution.
                                 16                 :                :  *
                                 17                 :                :  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
                                 18                 :                :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
                                 19                 :                :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
                                 20                 :                :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
                                 21                 :                :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
                                 22                 :                :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
                                 23                 :                :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
                                 24                 :                :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
                                 25                 :                :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
                                 26                 :                :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
                                 27                 :                :  * SUCH DAMAGE.
                                 28                 :                :  *
                                 29                 :                :  * contrib/pgcrypto/pgp-compress.c
                                 30                 :                :  */
                                 31                 :                : 
                                 32                 :                : #include "postgres.h"
                                 33                 :                : 
                                 34                 :                : #include "pgp.h"
                                 35                 :                : #include "px.h"
                                 36                 :                : 
                                 37                 :                : /*
                                 38                 :                :  * Compressed pkt writer
                                 39                 :                :  */
                                 40                 :                : 
                                 41                 :                : #ifdef HAVE_LIBZ
                                 42                 :                : 
                                 43                 :                : #include <zlib.h>
                                 44                 :                : 
                                 45                 :                : #define ZIP_OUT_BUF 8192
                                 46                 :                : #define ZIP_IN_BLOCK 8192
                                 47                 :                : 
                                 48                 :                : struct ZipStat
                                 49                 :                : {
                                 50                 :                :     uint8       type;
                                 51                 :                :     int         buf_len;
                                 52                 :                :     int         hdr_done;
                                 53                 :                :     z_stream    stream;
                                 54                 :                :     uint8       buf[ZIP_OUT_BUF];
                                 55                 :                : };
                                 56                 :                : 
                                 57                 :                : static void *
 6853 bruce@momjian.us           58                 :CBC          22 : z_alloc(void *priv, unsigned n_items, unsigned item_len)
                                 59                 :                : {
 1297 michael@paquier.xyz        60                 :             22 :     return palloc(n_items * item_len);
                                 61                 :                : }
                                 62                 :                : 
                                 63                 :                : static void
 6853 bruce@momjian.us           64                 :             22 : z_free(void *priv, void *addr)
                                 65                 :                : {
 1297 michael@paquier.xyz        66                 :             22 :     pfree(addr);
 6853 bruce@momjian.us           67                 :             22 : }
                                 68                 :                : 
                                 69                 :                : static int
 5421                            70                 :              3 : compress_init(PushFilter *next, void *init_arg, void **priv_p)
                                 71                 :                : {
                                 72                 :                :     int         res;
                                 73                 :                :     struct ZipStat *st;
 6853                            74                 :              3 :     PGP_Context *ctx = init_arg;
                                 75                 :              3 :     uint8       type = ctx->compress_algo;
                                 76                 :                : 
                                 77   [ +  +  -  + ]:              3 :     if (type != PGP_COMPR_ZLIB && type != PGP_COMPR_ZIP)
 6853 bruce@momjian.us           78                 :UBC           0 :         return PXE_PGP_UNSUPPORTED_COMPR;
                                 79                 :                : 
                                 80                 :                :     /*
                                 81                 :                :      * init
                                 82                 :                :      */
 1297 michael@paquier.xyz        83                 :CBC           3 :     st = palloc0(sizeof(*st));
 6853 bruce@momjian.us           84                 :              3 :     st->buf_len = ZIP_OUT_BUF;
                                 85                 :              3 :     st->stream.zalloc = z_alloc;
                                 86                 :              3 :     st->stream.zfree = z_free;
                                 87                 :                : 
                                 88         [ +  + ]:              3 :     if (type == PGP_COMPR_ZIP)
                                 89                 :              2 :         res = deflateInit2(&st->stream, ctx->compress_level,
                                 90                 :                :                            Z_DEFLATED, -15, 8, Z_DEFAULT_STRATEGY);
                                 91                 :                :     else
                                 92                 :              1 :         res = deflateInit(&st->stream, ctx->compress_level);
                                 93         [ -  + ]:              3 :     if (res != Z_OK)
                                 94                 :                :     {
 1297 michael@paquier.xyz        95                 :UBC           0 :         pfree(st);
 6853 bruce@momjian.us           96                 :              0 :         return PXE_PGP_COMPRESSION_ERROR;
                                 97                 :                :     }
 6853 bruce@momjian.us           98                 :CBC           3 :     *priv_p = st;
                                 99                 :                : 
                                100                 :              3 :     return ZIP_IN_BLOCK;
                                101                 :                : }
                                102                 :                : 
                                103                 :                : /* writes compressed data packet */
                                104                 :                : 
                                105                 :                : /* can handle zero-len incoming data, but shouldn't */
                                106                 :                : static int
 5421                           107                 :              4 : compress_process(PushFilter *next, void *priv, const uint8 *data, int len)
                                108                 :                : {
                                109                 :                :     int         res,
                                110                 :                :                 n_out;
 6853                           111                 :              4 :     struct ZipStat *st = priv;
                                112                 :                : 
                                113                 :                :     /*
                                114                 :                :      * process data
                                115                 :                :      */
  251 peter@eisentraut.org      116                 :GNC           4 :     st->stream.next_in = data;
 1361 tgl@sss.pgh.pa.us         117                 :CBC           4 :     st->stream.avail_in = len;
                                118         [ +  + ]:             12 :     while (st->stream.avail_in > 0)
                                119                 :                :     {
 6853 bruce@momjian.us          120                 :              4 :         st->stream.next_out = st->buf;
                                121                 :              4 :         st->stream.avail_out = st->buf_len;
 1361 tgl@sss.pgh.pa.us         122                 :              4 :         res = deflate(&st->stream, Z_NO_FLUSH);
 6853 bruce@momjian.us          123         [ -  + ]:              4 :         if (res != Z_OK)
 6853 bruce@momjian.us          124                 :UBC           0 :             return PXE_PGP_COMPRESSION_ERROR;
                                125                 :                : 
 6853 bruce@momjian.us          126                 :CBC           4 :         n_out = st->buf_len - st->stream.avail_out;
                                127         [ +  + ]:              4 :         if (n_out > 0)
                                128                 :                :         {
                                129                 :              1 :             res = pushf_write(next, st->buf, n_out);
                                130         [ -  + ]:              1 :             if (res < 0)
 6853 bruce@momjian.us          131                 :UBC           0 :                 return res;
                                132                 :                :         }
                                133                 :                :     }
                                134                 :                : 
 6853 bruce@momjian.us          135                 :CBC           4 :     return 0;
                                136                 :                : }
                                137                 :                : 
                                138                 :                : static int
 5421                           139                 :              3 : compress_flush(PushFilter *next, void *priv)
                                140                 :                : {
                                141                 :                :     int         res,
                                142                 :                :                 zres,
                                143                 :                :                 n_out;
 6853                           144                 :              3 :     struct ZipStat *st = priv;
                                145                 :                : 
                                146                 :              3 :     st->stream.next_in = NULL;
                                147                 :              3 :     st->stream.avail_in = 0;
                                148                 :                :     while (1)
                                149                 :                :     {
                                150                 :              4 :         st->stream.next_out = st->buf;
                                151                 :              4 :         st->stream.avail_out = st->buf_len;
                                152                 :              4 :         zres = deflate(&st->stream, Z_FINISH);
                                153   [ +  +  -  + ]:              4 :         if (zres != Z_STREAM_END && zres != Z_OK)
 6853 bruce@momjian.us          154                 :UBC           0 :             return PXE_PGP_COMPRESSION_ERROR;
                                155                 :                : 
 6853 bruce@momjian.us          156                 :CBC           4 :         n_out = st->buf_len - st->stream.avail_out;
                                157         [ +  - ]:              4 :         if (n_out > 0)
                                158                 :                :         {
                                159                 :              4 :             res = pushf_write(next, st->buf, n_out);
                                160         [ -  + ]:              4 :             if (res < 0)
 6853 bruce@momjian.us          161                 :UBC           0 :                 return res;
                                162                 :                :         }
 6853 bruce@momjian.us          163         [ +  + ]:CBC           4 :         if (zres == Z_STREAM_END)
                                164                 :              3 :             break;
                                165                 :                :     }
                                166                 :              3 :     return 0;
                                167                 :                : }
                                168                 :                : 
                                169                 :                : static void
                                170                 :              3 : compress_free(void *priv)
                                171                 :                : {
                                172                 :              3 :     struct ZipStat *st = priv;
                                173                 :                : 
                                174                 :              3 :     deflateEnd(&st->stream);
 3650                           175                 :              3 :     px_memset(st, 0, sizeof(*st));
 1297 michael@paquier.xyz       176                 :              3 :     pfree(st);
 6853 bruce@momjian.us          177                 :              3 : }
                                178                 :                : 
                                179                 :                : static const PushFilterOps
                                180                 :                :             compress_filter = {
                                181                 :                :     compress_init, compress_process, compress_flush, compress_free
                                182                 :                : };
                                183                 :                : 
                                184                 :                : int
 5421                           185                 :              3 : pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
                                186                 :                : {
 6853                           187                 :              3 :     return pushf_create(res, &compress_filter, ctx, dst);
                                188                 :                : }
                                189                 :                : 
                                190                 :                : /*
                                191                 :                :  * Decompress
                                192                 :                :  */
                                193                 :                : struct DecomprData
                                194                 :                : {
                                195                 :                :     int         buf_len;        /* = ZIP_OUT_BUF */
                                196                 :                :     int         buf_data;       /* available data */
                                197                 :                :     uint8      *pos;
                                198                 :                :     z_stream    stream;
                                199                 :                :     int         eof;
                                200                 :                :     uint8       buf[ZIP_OUT_BUF];
                                201                 :                : };
                                202                 :                : 
                                203                 :                : static int
 5421                           204                 :              4 : decompress_init(void **priv_p, void *arg, PullFilter *src)
                                205                 :                : {
 6853                           206                 :              4 :     PGP_Context *ctx = arg;
                                207                 :                :     struct DecomprData *dec;
                                208                 :                :     int         res;
                                209                 :                : 
                                210         [ +  + ]:              4 :     if (ctx->compress_algo != PGP_COMPR_ZLIB
 6756                           211         [ -  + ]:              3 :         && ctx->compress_algo != PGP_COMPR_ZIP)
 6853 bruce@momjian.us          212                 :UBC           0 :         return PXE_PGP_UNSUPPORTED_COMPR;
                                213                 :                : 
 1297 michael@paquier.xyz       214                 :CBC           4 :     dec = palloc0(sizeof(*dec));
 6853 bruce@momjian.us          215                 :              4 :     dec->buf_len = ZIP_OUT_BUF;
                                216                 :              4 :     *priv_p = dec;
                                217                 :                : 
                                218                 :              4 :     dec->stream.zalloc = z_alloc;
                                219                 :              4 :     dec->stream.zfree = z_free;
                                220                 :                : 
                                221         [ +  + ]:              4 :     if (ctx->compress_algo == PGP_COMPR_ZIP)
                                222                 :              3 :         res = inflateInit2(&dec->stream, -15);
                                223                 :                :     else
                                224                 :              1 :         res = inflateInit(&dec->stream);
                                225         [ -  + ]:              4 :     if (res != Z_OK)
                                226                 :                :     {
 1297 michael@paquier.xyz       227                 :UBC           0 :         pfree(dec);
 6853 bruce@momjian.us          228                 :              0 :         px_debug("decompress_init: inflateInit error");
                                229                 :              0 :         return PXE_PGP_COMPRESSION_ERROR;
                                230                 :                :     }
                                231                 :                : 
 6853 bruce@momjian.us          232                 :CBC           4 :     return 0;
                                233                 :                : }
                                234                 :                : 
                                235                 :                : static int
 5421                           236                 :             36 : decompress_read(void *priv, PullFilter *src, int len,
                                237                 :                :                 uint8 **data_p, uint8 *buf, int buflen)
                                238                 :                : {
                                239                 :                :     int         res;
                                240                 :                :     int         flush;
 6853                           241                 :             36 :     struct DecomprData *dec = priv;
                                242                 :                : 
                                243                 :             44 : restart:
                                244         [ +  + ]:             44 :     if (dec->buf_data > 0)
                                245                 :                :     {
                                246         [ +  + ]:             32 :         if (len > dec->buf_data)
                                247                 :              4 :             len = dec->buf_data;
                                248                 :             32 :         *data_p = dec->pos;
                                249                 :             32 :         dec->pos += len;
                                250                 :             32 :         dec->buf_data -= len;
                                251                 :             32 :         return len;
                                252                 :                :     }
                                253                 :                : 
                                254         [ +  + ]:             12 :     if (dec->eof)
                                255                 :              4 :         return 0;
                                256                 :                : 
 1361 michael@paquier.xyz       257         [ +  - ]:              8 :     if (dec->stream.avail_in == 0)
                                258                 :                :     {
                                259                 :                :         uint8      *tmp;
                                260                 :                : 
                                261                 :              8 :         res = pullf_read(src, 8192, &tmp);
                                262         [ -  + ]:              8 :         if (res < 0)
 1361 michael@paquier.xyz       263                 :UBC           0 :             return res;
 1361 michael@paquier.xyz       264                 :CBC           8 :         dec->stream.next_in = tmp;
                                265                 :              8 :         dec->stream.avail_in = res;
                                266                 :                :     }
                                267                 :                : 
 6853 bruce@momjian.us          268                 :              8 :     dec->stream.next_out = dec->buf;
                                269                 :              8 :     dec->stream.avail_out = dec->buf_len;
                                270                 :              8 :     dec->pos = dec->buf;
                                271                 :                : 
                                272                 :                :     /*
                                273                 :                :      * Z_SYNC_FLUSH is tell zlib to output as much as possible. It should do
                                274                 :                :      * it anyway (Z_NO_FLUSH), but seems to reserve the right not to.  So lets
                                275                 :                :      * follow the API.
                                276                 :                :      */
                                277         [ +  - ]:              8 :     flush = dec->stream.avail_in ? Z_SYNC_FLUSH : Z_FINISH;
                                278                 :              8 :     res = inflate(&dec->stream, flush);
                                279   [ +  +  -  + ]:              8 :     if (res != Z_OK && res != Z_STREAM_END)
                                280                 :                :     {
 6853 bruce@momjian.us          281                 :UBC           0 :         px_debug("decompress_read: inflate error: %d", res);
                                282                 :              0 :         return PXE_PGP_CORRUPT_DATA;
                                283                 :                :     }
                                284                 :                : 
 6853 bruce@momjian.us          285                 :CBC           8 :     dec->buf_data = dec->buf_len - dec->stream.avail_out;
                                286         [ +  + ]:              8 :     if (res == Z_STREAM_END)
                                287                 :                :     {
                                288                 :                :         uint8      *tmp;
                                289                 :                : 
                                290                 :                :         /*
                                291                 :                :          * A stream must be terminated by a normal packet.  If the last stream
                                292                 :                :          * packet in the source stream is a full packet, a normal empty packet
                                293                 :                :          * must follow.  Since the underlying packet reader doesn't know that
                                294                 :                :          * the compressed stream has been ended, we need to consume the
                                295                 :                :          * terminating packet here.  This read does not harm even if the
                                296                 :                :          * stream has already ended.
                                297                 :                :          */
 1357 michael@paquier.xyz       298                 :              4 :         res = pullf_read(src, 1, &tmp);
                                299                 :                : 
                                300         [ -  + ]:              4 :         if (res < 0)
 1357 michael@paquier.xyz       301                 :UBC           0 :             return res;
 1357 michael@paquier.xyz       302         [ -  + ]:CBC           4 :         else if (res > 0)
                                303                 :                :         {
 1357 michael@paquier.xyz       304                 :UBC           0 :             px_debug("decompress_read: extra bytes after end of stream");
                                305                 :              0 :             return PXE_PGP_CORRUPT_DATA;
                                306                 :                :         }
 6853 bruce@momjian.us          307                 :CBC           4 :         dec->eof = 1;
                                308                 :                :     }
                                309                 :              8 :     goto restart;
                                310                 :                : }
                                311                 :                : 
                                312                 :                : static void
 6756                           313                 :              4 : decompress_free(void *priv)
                                314                 :                : {
 6853                           315                 :              4 :     struct DecomprData *dec = priv;
                                316                 :                : 
                                317                 :              4 :     inflateEnd(&dec->stream);
 3650                           318                 :              4 :     px_memset(dec, 0, sizeof(*dec));
 1297 michael@paquier.xyz       319                 :              4 :     pfree(dec);
 6853 bruce@momjian.us          320                 :              4 : }
                                321                 :                : 
                                322                 :                : static const PullFilterOps
                                323                 :                :             decompress_filter = {
                                324                 :                :     decompress_init, decompress_read, decompress_free
                                325                 :                : };
                                326                 :                : 
                                327                 :                : int
 5421                           328                 :              4 : pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
                                329                 :                : {
 6853                           330                 :              4 :     return pullf_create(res, &decompress_filter, ctx, src);
                                331                 :                : }
                                332                 :                : #else                           /* !HAVE_LIBZ */
                                333                 :                : 
                                334                 :                : int
                                335                 :                : pgp_compress_filter(PushFilter **res, PGP_Context *ctx, PushFilter *dst)
                                336                 :                : {
                                337                 :                :     return PXE_PGP_UNSUPPORTED_COMPR;
                                338                 :                : }
                                339                 :                : 
                                340                 :                : int
                                341                 :                : pgp_decompress_filter(PullFilter **res, PGP_Context *ctx, PullFilter *src)
                                342                 :                : {
                                343                 :                :     return PXE_PGP_UNSUPPORTED_COMPR;
                                344                 :                : }
                                345                 :                : 
                                346                 :                : #endif
        

Generated by: LCOV version 2.1-beta2-3-g6141622