LCOV - code coverage report
Current view: top level - lib - decompress_inflate.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 37 71 52.1 %
Date: 2015-04-12 14:34:49 Functions: 1 2 50.0 %

          Line data    Source code
       1             : #ifdef STATIC
       2             : /* Pre-boot environment: included */
       3             : 
       4             : /* prevent inclusion of _LINUX_KERNEL_H in pre-boot environment: lots
       5             :  * errors about console_printk etc... on ARM */
       6             : #define _LINUX_KERNEL_H
       7             : 
       8             : #include "zlib_inflate/inftrees.c"
       9             : #include "zlib_inflate/inffast.c"
      10             : #include "zlib_inflate/inflate.c"
      11             : 
      12             : #else /* STATIC */
      13             : /* initramfs et al: linked */
      14             : 
      15             : #include <linux/zutil.h>
      16             : 
      17             : #include "zlib_inflate/inftrees.h"
      18             : #include "zlib_inflate/inffast.h"
      19             : #include "zlib_inflate/inflate.h"
      20             : 
      21             : #include "zlib_inflate/infutil.h"
      22             : #include <linux/decompress/inflate.h>
      23             : 
      24             : #endif /* STATIC */
      25             : 
      26             : #include <linux/decompress/mm.h>
      27             : 
      28             : #define GZIP_IOBUF_SIZE (16*1024)
      29             : 
      30           0 : static long INIT nofill(void *buffer, unsigned long len)
      31             : {
      32           0 :         return -1;
      33             : }
      34             : 
      35             : /* Included from initramfs et al code */
      36           1 : STATIC int INIT gunzip(unsigned char *buf, long len,
      37             :                        long (*fill)(void*, unsigned long),
      38             :                        long (*flush)(void*, unsigned long),
      39             :                        unsigned char *out_buf,
      40             :                        long *pos,
      41             :                        void(*error)(char *x)) {
      42             :         u8 *zbuf;
      43             :         struct z_stream_s *strm;
      44             :         int rc;
      45             :         size_t out_len;
      46             : 
      47             :         rc = -1;
      48           1 :         if (flush) {
      49             :                 out_len = 0x8000; /* 32 K */
      50             :                 out_buf = malloc(out_len);
      51             :         } else {
      52           0 :                 out_len = ((size_t)~0) - (size_t)out_buf; /* no limit */
      53             :         }
      54           1 :         if (!out_buf) {
      55           0 :                 error("Out of memory while allocating output buffer");
      56           0 :                 goto gunzip_nomem1;
      57             :         }
      58             : 
      59           1 :         if (buf)
      60             :                 zbuf = buf;
      61             :         else {
      62             :                 zbuf = malloc(GZIP_IOBUF_SIZE);
      63             :                 len = 0;
      64             :         }
      65           1 :         if (!zbuf) {
      66           0 :                 error("Out of memory while allocating input buffer");
      67           0 :                 goto gunzip_nomem2;
      68             :         }
      69             : 
      70             :         strm = malloc(sizeof(*strm));
      71           1 :         if (strm == NULL) {
      72           0 :                 error("Out of memory while allocating z_stream");
      73           0 :                 goto gunzip_nomem3;
      74             :         }
      75             : 
      76           2 :         strm->workspace = malloc(flush ? zlib_inflate_workspacesize() :
      77             :                                  sizeof(struct inflate_state));
      78           1 :         if (strm->workspace == NULL) {
      79           0 :                 error("Out of memory while allocating workspace");
      80           0 :                 goto gunzip_nomem4;
      81             :         }
      82             : 
      83           1 :         if (!fill)
      84             :                 fill = nofill;
      85             : 
      86           1 :         if (len == 0)
      87           0 :                 len = fill(zbuf, GZIP_IOBUF_SIZE);
      88             : 
      89             :         /* verify the gzip header */
      90           2 :         if (len < 10 ||
      91           2 :            zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) {
      92           0 :                 if (pos)
      93           0 :                         *pos = 0;
      94           0 :                 error("Not a gzip file");
      95           0 :                 goto gunzip_5;
      96             :         }
      97             : 
      98             :         /* skip over gzip header (1f,8b,08... 10 bytes total +
      99             :          * possible asciz filename)
     100             :          */
     101           1 :         strm->next_in = zbuf + 10;
     102           1 :         strm->avail_in = len - 10;
     103             :         /* skip over asciz filename */
     104           1 :         if (zbuf[3] & 0x8) {
     105             :                 do {
     106             :                         /*
     107             :                          * If the filename doesn't fit into the buffer,
     108             :                          * the file is very probably corrupt. Don't try
     109             :                          * to read more data.
     110             :                          */
     111           0 :                         if (strm->avail_in == 0) {
     112           0 :                                 error("header error");
     113           0 :                                 goto gunzip_5;
     114             :                         }
     115           0 :                         --strm->avail_in;
     116           0 :                 } while (*strm->next_in++);
     117             :         }
     118             : 
     119           1 :         strm->next_out = out_buf;
     120           1 :         strm->avail_out = out_len;
     121             : 
     122           1 :         rc = zlib_inflateInit2(strm, -MAX_WBITS);
     123             : 
     124           1 :         if (!flush) {
     125           0 :                 WS(strm)->inflate_state.wsize = 0;
     126           0 :                 WS(strm)->inflate_state.window = NULL;
     127             :         }
     128             : 
     129           1 :         while (rc == Z_OK) {
     130           1 :                 if (strm->avail_in == 0) {
     131             :                         /* TODO: handle case where both pos and fill are set */
     132           0 :                         len = fill(zbuf, GZIP_IOBUF_SIZE);
     133           0 :                         if (len < 0) {
     134             :                                 rc = -1;
     135           0 :                                 error("read error");
     136           0 :                                 break;
     137             :                         }
     138           0 :                         strm->next_in = zbuf;
     139           0 :                         strm->avail_in = len;
     140             :                 }
     141           1 :                 rc = zlib_inflate(strm, 0);
     142             : 
     143             :                 /* Write any data generated */
     144           1 :                 if (flush && strm->next_out > out_buf) {
     145           1 :                         long l = strm->next_out - out_buf;
     146           1 :                         if (l != flush(out_buf, l)) {
     147             :                                 rc = -1;
     148           0 :                                 error("write error");
     149           0 :                                 break;
     150             :                         }
     151           1 :                         strm->next_out = out_buf;
     152           1 :                         strm->avail_out = out_len;
     153             :                 }
     154             : 
     155             :                 /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
     156           1 :                 if (rc == Z_STREAM_END) {
     157             :                         rc = 0;
     158             :                         break;
     159           0 :                 } else if (rc != Z_OK) {
     160           0 :                         error("uncompression error");
     161             :                         rc = -1;
     162             :                 }
     163             :         }
     164             : 
     165           1 :         zlib_inflateEnd(strm);
     166           1 :         if (pos)
     167             :                 /* add + 8 to skip over trailer */
     168           1 :                 *pos = strm->next_in - zbuf+8;
     169             : 
     170             : gunzip_5:
     171           1 :         free(strm->workspace);
     172             : gunzip_nomem4:
     173           1 :         free(strm);
     174             : gunzip_nomem3:
     175           1 :         if (!buf)
     176           0 :                 free(zbuf);
     177             : gunzip_nomem2:
     178           1 :         if (flush)
     179           1 :                 free(out_buf);
     180             : gunzip_nomem1:
     181           1 :         return rc; /* returns Z_OK (0) if successful */
     182             : }
     183             : 
     184             : #define decompress gunzip

Generated by: LCOV version 1.11