LCOV - code coverage report
Current view: top level - src/vendor/tinf - tinfgzip.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 53.6 % 56 30
Test Date: 2026-04-20 19:54:22 Functions: 66.7 % 3 2

            Line data    Source code
       1              : /* SPDX-License-Identifier: Zlib */
       2              : 
       3              : /*
       4              :  * tinfgzip - tiny gzip decompressor
       5              :  *
       6              :  * Copyright (c) 2003-2019 Joergen Ibsen
       7              :  *
       8              :  * This software is provided 'as-is', without any express or implied
       9              :  * warranty. In no event will the authors be held liable for any damages
      10              :  * arising from the use of this software.
      11              :  *
      12              :  * Permission is granted to anyone to use this software for any purpose,
      13              :  * including commercial applications, and to alter it and redistribute it
      14              :  * freely, subject to the following restrictions:
      15              :  *
      16              :  *   1. The origin of this software must not be misrepresented; you must
      17              :  *      not claim that you wrote the original software. If you use this
      18              :  *      software in a product, an acknowledgment in the product
      19              :  *      documentation would be appreciated but is not required.
      20              :  *
      21              :  *   2. Altered source versions must be plainly marked as such, and must
      22              :  *      not be misrepresented as being the original software.
      23              :  *
      24              :  *   3. This notice may not be removed or altered from any source
      25              :  *      distribution.
      26              :  */
      27              : 
      28              : #include "tinf.h"
      29              : 
      30              : typedef enum {
      31              :         FTEXT    = 1,
      32              :         FHCRC    = 2,
      33              :         FEXTRA   = 4,
      34              :         FNAME    = 8,
      35              :         FCOMMENT = 16
      36              : } tinf_gzip_flag;
      37              : 
      38            0 : static unsigned int read_le16(const unsigned char *p)
      39              : {
      40            0 :         return ((unsigned int) p[0])
      41            0 :              | ((unsigned int) p[1] << 8);
      42              : }
      43              : 
      44           12 : static unsigned int read_le32(const unsigned char *p)
      45              : {
      46           12 :         return ((unsigned int) p[0])
      47           12 :              | ((unsigned int) p[1] << 8)
      48           12 :              | ((unsigned int) p[2] << 16)
      49           12 :              | ((unsigned int) p[3] << 24);
      50              : }
      51              : 
      52            9 : int tinf_gzip_uncompress(void *dest, unsigned int *destLen,
      53              :                          const void *source, unsigned int sourceLen)
      54              : {
      55            9 :         const unsigned char *src = (const unsigned char *) source;
      56            9 :         unsigned char *dst = (unsigned char *) dest;
      57              :         const unsigned char *start;
      58              :         unsigned int dlen, crc32;
      59              :         int res;
      60              :         unsigned char flg;
      61              : 
      62              :         /* -- Check header -- */
      63              : 
      64              :         /* Check room for at least 10 byte header and 8 byte trailer */
      65            9 :         if (sourceLen < 18) {
      66            1 :                 return TINF_DATA_ERROR;
      67              :         }
      68              : 
      69              :         /* Check id bytes */
      70            8 :         if (src[0] != 0x1F || src[1] != 0x8B) {
      71            2 :                 return TINF_DATA_ERROR;
      72              :         }
      73              : 
      74              :         /* Check method is deflate */
      75            6 :         if (src[2] != 8) {
      76            0 :                 return TINF_DATA_ERROR;
      77              :         }
      78              : 
      79              :         /* Get flag byte */
      80            6 :         flg = src[3];
      81              : 
      82              :         /* Check that reserved bits are zero */
      83            6 :         if (flg & 0xE0) {
      84            0 :                 return TINF_DATA_ERROR;
      85              :         }
      86              : 
      87              :         /* -- Find start of compressed data -- */
      88              : 
      89              :         /* Skip base header of 10 bytes */
      90            6 :         start = src + 10;
      91              : 
      92              :         /* Skip extra data if present */
      93            6 :         if (flg & FEXTRA) {
      94            0 :                 unsigned int xlen = read_le16(start);
      95              : 
      96            0 :                 if (xlen > sourceLen - 12) {
      97            0 :                         return TINF_DATA_ERROR;
      98              :                 }
      99              : 
     100            0 :                 start += xlen + 2;
     101              :         }
     102              : 
     103              :         /* Skip file name if present */
     104            6 :         if (flg & FNAME) {
     105              :                 do {
     106            0 :                         if (start - src >= sourceLen) {
     107            0 :                                 return TINF_DATA_ERROR;
     108              :                         }
     109            0 :                 } while (*start++);
     110              :         }
     111              : 
     112              :         /* Skip file comment if present */
     113            6 :         if (flg & FCOMMENT) {
     114              :                 do {
     115            0 :                         if (start - src >= sourceLen) {
     116            0 :                                 return TINF_DATA_ERROR;
     117              :                         }
     118            0 :                 } while (*start++);
     119              :         }
     120              : 
     121              :         /* Check header crc if present */
     122            6 :         if (flg & FHCRC) {
     123              :                 unsigned int hcrc;
     124              : 
     125            0 :                 if (start - src > sourceLen - 2) {
     126            0 :                         return TINF_DATA_ERROR;
     127              :                 }
     128              : 
     129            0 :                 hcrc = read_le16(start);
     130              : 
     131            0 :                 if (hcrc != (tinf_crc32(src, start - src) & 0x0000FFFF)) {
     132            0 :                         return TINF_DATA_ERROR;
     133              :                 }
     134              : 
     135            0 :                 start += 2;
     136              :         }
     137              : 
     138              :         /* -- Get decompressed length -- */
     139              : 
     140            6 :         dlen = read_le32(&src[sourceLen - 4]);
     141              : 
     142            6 :         if (dlen > *destLen) {
     143            0 :                 return TINF_BUF_ERROR;
     144              :         }
     145              : 
     146              :         /* -- Get CRC32 checksum of original data -- */
     147              : 
     148            6 :         crc32 = read_le32(&src[sourceLen - 8]);
     149              : 
     150              :         /* -- Decompress data -- */
     151              : 
     152            6 :         if ((src + sourceLen) - start < 8) {
     153            0 :                 return TINF_DATA_ERROR;
     154              :         }
     155              : 
     156            6 :         res = tinf_uncompress(dst, destLen, start,
     157            6 :                               (src + sourceLen) - start - 8);
     158              : 
     159            6 :         if (res != TINF_OK) {
     160            0 :                 return TINF_DATA_ERROR;
     161              :         }
     162              : 
     163            6 :         if (*destLen != dlen) {
     164            0 :                 return TINF_DATA_ERROR;
     165              :         }
     166              : 
     167              :         /* -- Check CRC32 checksum -- */
     168              : 
     169            6 :         if (crc32 != tinf_crc32(dst, dlen)) {
     170            0 :                 return TINF_DATA_ERROR;
     171              :         }
     172              : 
     173            6 :         return TINF_OK;
     174              : }
        

Generated by: LCOV version 2.0-1