LCOV - code coverage report
Current view: top level - g10 - compress-bz2.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 58 125 46.4 %
Date: 2015-11-05 17:10:59 Functions: 3 5 60.0 %

          Line data    Source code
       1             : /* compress.c - bzip2 compress filter
       2             :  * Copyright (C) 2003, 2004 Free Software Foundation, Inc.
       3             :  *
       4             :  * This file is part of GnuPG.
       5             :  *
       6             :  * GnuPG is free software; you can redistribute it and/or modify
       7             :  * it under the terms of the GNU General Public License as published by
       8             :  * the Free Software Foundation; either version 3 of the License, or
       9             :  * (at your option) any later version.
      10             :  *
      11             :  * GnuPG is distributed in the hope that it will be useful,
      12             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :  * GNU General Public License for more details.
      15             :  *
      16             :  * You should have received a copy of the GNU General Public License
      17             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      18             :  */
      19             : 
      20             : #include <config.h>
      21             : #include <string.h>
      22             : #include <stdio.h> /* Early versions of bzlib (1.0) require stdio.h */
      23             : #include <bzlib.h>
      24             : 
      25             : #include "gpg.h"
      26             : #include "util.h"
      27             : #include "packet.h"
      28             : #include "filter.h"
      29             : #include "main.h"
      30             : #include "options.h"
      31             : 
      32             : /* Note that the code in compress.c is nearly identical to the code
      33             :    here, so if you fix a bug here, look there to see if a matching bug
      34             :    needs to be fixed.  I tried to have one set of functions that could
      35             :    do ZIP, ZLIB, and BZIP2, but it became dangerously unreadable with
      36             :    #ifdefs and if(algo) -dshaw */
      37             : 
      38             : static void
      39           0 : init_compress( compress_filter_context_t *zfx, bz_stream *bzs )
      40             : {
      41             :   int rc;
      42             :   int level;
      43             : 
      44           0 :   if( opt.bz2_compress_level >= 1 && opt.bz2_compress_level <= 9 )
      45           0 :     level = opt.bz2_compress_level;
      46           0 :   else if( opt.bz2_compress_level == -1 )
      47           0 :     level = 6; /* no particular reason, but it seems reasonable */
      48             :   else
      49             :     {
      50           0 :       log_error("invalid compression level; using default level\n");
      51           0 :       level = 6;
      52             :     }
      53             : 
      54           0 :   if((rc=BZ2_bzCompressInit(bzs,level,0,0))!=BZ_OK)
      55           0 :     log_fatal("bz2lib problem: %d\n",rc);
      56             : 
      57           0 :   zfx->outbufsize = 8192;
      58           0 :   zfx->outbuf = xmalloc( zfx->outbufsize );
      59           0 : }
      60             : 
      61             : static int
      62           0 : do_compress(compress_filter_context_t *zfx, bz_stream *bzs, int flush, IOBUF a)
      63             : {
      64             :   int rc;
      65             :   int zrc;
      66             :   unsigned n;
      67             : 
      68             :   do
      69             :     {
      70           0 :       bzs->next_out = zfx->outbuf;
      71           0 :       bzs->avail_out = zfx->outbufsize;
      72           0 :       if( DBG_FILTER )
      73           0 :         log_debug("enter bzCompress: avail_in=%u, avail_out=%u, flush=%d\n",
      74             :                   (unsigned)bzs->avail_in, (unsigned)bzs->avail_out, flush );
      75           0 :       zrc = BZ2_bzCompress( bzs, flush );
      76           0 :       if( zrc == BZ_STREAM_END && flush == BZ_FINISH )
      77             :         ;
      78           0 :       else if( zrc != BZ_RUN_OK && zrc != BZ_FINISH_OK )
      79           0 :         log_fatal("bz2lib deflate problem: rc=%d\n", zrc );
      80             : 
      81           0 :       n = zfx->outbufsize - bzs->avail_out;
      82           0 :       if( DBG_FILTER )
      83           0 :         log_debug("leave bzCompress:"
      84             :                   " avail_in=%u, avail_out=%u, n=%u, zrc=%d\n",
      85             :                   (unsigned)bzs->avail_in, (unsigned)bzs->avail_out,
      86             :                   (unsigned)n, zrc );
      87             : 
      88           0 :       if( (rc=iobuf_write( a, zfx->outbuf, n )) )
      89             :         {
      90           0 :           log_debug("bzCompress: iobuf_write failed\n");
      91           0 :           return rc;
      92             :         }
      93             :     }
      94           0 :   while( bzs->avail_in || (flush == BZ_FINISH && zrc != BZ_STREAM_END) );
      95             : 
      96           0 :   return 0;
      97             : }
      98             : 
      99             : static void
     100           1 : init_uncompress( compress_filter_context_t *zfx, bz_stream *bzs )
     101             : {
     102             :   int rc;
     103             : 
     104           1 :   if((rc=BZ2_bzDecompressInit(bzs,0,opt.bz2_decompress_lowmem))!=BZ_OK)
     105           0 :     log_fatal("bz2lib problem: %d\n",rc);
     106             : 
     107           1 :   zfx->inbufsize = 2048;
     108           1 :   zfx->inbuf = xmalloc( zfx->inbufsize );
     109           1 :   bzs->avail_in = 0;
     110           1 : }
     111             : 
     112             : static int
     113      524289 : do_uncompress( compress_filter_context_t *zfx, bz_stream *bzs,
     114             :                IOBUF a, size_t *ret_len )
     115             : {
     116             :   int zrc;
     117      524289 :   int rc=0;
     118             :   size_t n;
     119             :   int nread, count;
     120      524289 :   int refill = !bzs->avail_in;
     121      524289 :   int eofseen = 0;
     122             : 
     123      524289 :   if( DBG_FILTER )
     124           0 :     log_debug("begin bzDecompress: avail_in=%u, avail_out=%u, inbuf=%u\n",
     125             :               (unsigned)bzs->avail_in, (unsigned)bzs->avail_out,
     126             :               (unsigned)zfx->inbufsize );
     127             :   do
     128             :     {
     129      524291 :       if( bzs->avail_in < zfx->inbufsize && refill )
     130             :         {
     131           3 :           n = bzs->avail_in;
     132           3 :           if( !n )
     133           3 :             bzs->next_in = zfx->inbuf;
     134           3 :           count = zfx->inbufsize - n;
     135           3 :           nread = iobuf_read( a, zfx->inbuf + n, count );
     136           3 :           if( nread == -1 )
     137             :             {
     138           0 :               eofseen = 1;
     139           0 :               nread = 0;
     140             :             }
     141           3 :           n += nread;
     142           3 :           bzs->avail_in = n;
     143             :         }
     144      524291 :       if (!eofseen)
     145      524291 :         refill = 1;
     146             : 
     147      524291 :       if( DBG_FILTER )
     148           0 :         log_debug("enter bzDecompress: avail_in=%u, avail_out=%u\n",
     149             :                   (unsigned)bzs->avail_in, (unsigned)bzs->avail_out);
     150             : 
     151      524291 :       zrc=BZ2_bzDecompress(bzs);
     152      524291 :       if( DBG_FILTER )
     153           0 :         log_debug("leave bzDecompress: avail_in=%u, avail_out=%u, zrc=%d\n",
     154             :                   (unsigned)bzs->avail_in, (unsigned)bzs->avail_out, zrc);
     155      524291 :       if( zrc == BZ_STREAM_END )
     156           1 :         rc = -1; /* eof */
     157      524290 :       else if( zrc != BZ_OK && zrc != BZ_PARAM_ERROR )
     158           0 :         log_fatal("bz2lib inflate problem: rc=%d\n", zrc );
     159      524290 :       else if (zrc == BZ_OK && eofseen
     160           0 :                && !bzs->avail_in && bzs->avail_out > 0)
     161             :         {
     162           0 :           log_error ("unexpected EOF in bz2lib\n");
     163           0 :           rc = GPG_ERR_BAD_DATA;
     164           0 :           break;
     165             :         }
     166             :     }
     167      524291 :   while( bzs->avail_out && zrc != BZ_STREAM_END && zrc != BZ_PARAM_ERROR );
     168             : 
     169             :   /* I'm not completely happy with the two uses of BZ_PARAM_ERROR
     170             :      here.  The corresponding zlib function is Z_BUF_ERROR, which
     171             :      covers a narrower scope than BZ_PARAM_ERROR. -dshaw */
     172             : 
     173      524289 :   *ret_len = zfx->outbufsize - bzs->avail_out;
     174      524289 :   if( DBG_FILTER )
     175           0 :     log_debug("do_uncompress: returning %u bytes\n", (unsigned)*ret_len );
     176      524289 :   return rc;
     177             : }
     178             : 
     179             : int
     180      524291 : compress_filter_bz2( void *opaque, int control,
     181             :                      IOBUF a, byte *buf, size_t *ret_len)
     182             : {
     183      524291 :   size_t size = *ret_len;
     184      524291 :   compress_filter_context_t *zfx = opaque;
     185      524291 :   bz_stream *bzs = zfx->opaque;
     186      524291 :   int rc=0;
     187             : 
     188      524291 :   if( control == IOBUFCTRL_UNDERFLOW )
     189             :     {
     190      524289 :       if( !zfx->status )
     191             :         {
     192           1 :           bzs = zfx->opaque = xmalloc_clear( sizeof *bzs );
     193           1 :           init_uncompress( zfx, bzs );
     194           1 :           zfx->status = 1;
     195             :         }
     196             : 
     197      524289 :       bzs->next_out = buf;
     198      524289 :       bzs->avail_out = size;
     199      524289 :       zfx->outbufsize = size; /* needed only for calculation */
     200      524289 :       rc = do_uncompress( zfx, bzs, a, ret_len );
     201             :     }
     202           2 :   else if( control == IOBUFCTRL_FLUSH )
     203             :     {
     204           0 :       if( !zfx->status )
     205             :         {
     206             :           PACKET pkt;
     207             :           PKT_compressed cd;
     208             : 
     209           0 :           if( zfx->algo != COMPRESS_ALGO_BZIP2 )
     210           0 :             BUG();
     211           0 :           memset( &cd, 0, sizeof cd );
     212           0 :           cd.len = 0;
     213           0 :           cd.algorithm = zfx->algo;
     214           0 :           init_packet( &pkt );
     215           0 :           pkt.pkttype = PKT_COMPRESSED;
     216           0 :           pkt.pkt.compressed = &cd;
     217           0 :           if( build_packet( a, &pkt ))
     218           0 :             log_bug("build_packet(PKT_COMPRESSED) failed\n");
     219           0 :           bzs = zfx->opaque = xmalloc_clear( sizeof *bzs );
     220           0 :           init_compress( zfx, bzs );
     221           0 :           zfx->status = 2;
     222             :         }
     223             : 
     224           0 :       bzs->next_in = buf;
     225           0 :       bzs->avail_in = size;
     226           0 :       rc = do_compress( zfx, bzs, BZ_RUN, a );
     227             :     }
     228           2 :   else if( control == IOBUFCTRL_FREE )
     229             :     {
     230           1 :       if( zfx->status == 1 )
     231             :         {
     232           1 :           BZ2_bzDecompressEnd(bzs);
     233           1 :           xfree(bzs);
     234           1 :           zfx->opaque = NULL;
     235           1 :           xfree(zfx->outbuf); zfx->outbuf = NULL;
     236             :         }
     237           0 :       else if( zfx->status == 2 )
     238             :         {
     239           0 :           bzs->next_in = buf;
     240           0 :           bzs->avail_in = 0;
     241           0 :           do_compress( zfx, bzs, BZ_FINISH, a );
     242           0 :           BZ2_bzCompressEnd(bzs);
     243           0 :           xfree(bzs);
     244           0 :           zfx->opaque = NULL;
     245           0 :           xfree(zfx->outbuf); zfx->outbuf = NULL;
     246             :         }
     247           1 :       if (zfx->release)
     248           1 :         zfx->release (zfx);
     249             :     }
     250           1 :   else if( control == IOBUFCTRL_DESC )
     251           0 :     *(char**)buf = "compress_filter";
     252      524291 :   return rc;
     253             : }

Generated by: LCOV version 1.11