197 lines
8.0 KiB
C
197 lines
8.0 KiB
C
|
/*
|
||
|
* This file contains code from zlib library v.1.2.3 with modifications
|
||
|
* by aCaB <acab@clamav.net> to allow decompression of deflate64 streams
|
||
|
* (aka zip method 9). The implementation is heavily inspired by InfoZip
|
||
|
* and zlib's inf9back.c
|
||
|
*
|
||
|
* Full copy of the original zlib license follows:
|
||
|
*/
|
||
|
|
||
|
/* zlib.h -- interface of the 'zlib' general purpose compression library
|
||
|
version 1.2.3, July 18th, 2005
|
||
|
|
||
|
Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
|
||
|
|
||
|
This software is provided 'as-is', without any express or implied
|
||
|
warranty. In no event will the authors be held liable for any damages
|
||
|
arising from the use of this software.
|
||
|
|
||
|
Permission is granted to anyone to use this software for any purpose,
|
||
|
including commercial applications, and to alter it and redistribute it
|
||
|
freely, subject to the following restrictions:
|
||
|
|
||
|
1. The origin of this software must not be misrepresented; you must not
|
||
|
claim that you wrote the original software. If you use this software
|
||
|
in a product, an acknowledgment in the product documentation would be
|
||
|
appreciated but is not required.
|
||
|
2. Altered source versions must be plainly marked as such, and must not be
|
||
|
misrepresented as being the original software.
|
||
|
3. This notice may not be removed or altered from any source distribution.
|
||
|
|
||
|
Jean-loup Gailly Mark Adler
|
||
|
jloup@gzip.org madler@alumni.caltech.edu
|
||
|
|
||
|
|
||
|
The data format used by the zlib library is described by RFCs (Request for
|
||
|
Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
|
||
|
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
|
||
|
*/
|
||
|
|
||
|
#ifndef __INFLATE64_PRIV_H
|
||
|
#define __INFLATE64_PRIV_H
|
||
|
|
||
|
#if HAVE_CONFIG_H
|
||
|
#include "clamav-config.h"
|
||
|
#endif
|
||
|
|
||
|
#include "inflate64.h"
|
||
|
|
||
|
#include <zlib.h> /* adler/crc32 */
|
||
|
|
||
|
#ifndef Z_BLOCK
|
||
|
#define Z_BLOCK 5
|
||
|
#endif
|
||
|
|
||
|
#ifndef local
|
||
|
# define local static
|
||
|
#endif
|
||
|
/* compile with -Dlocal if your debugger can't find static symbols */
|
||
|
|
||
|
#ifndef PKZIP_BUG_WORKAROUND
|
||
|
#define PKZIP_BUG_WORKAROUND
|
||
|
#endif
|
||
|
|
||
|
/* Diagnostic functions */
|
||
|
#ifdef INF64DEBUG
|
||
|
# include <stdio.h>
|
||
|
# define Assert(cond,msg) {if(!(cond)) perror(msg);}
|
||
|
# define Trace(x) {if (verbose>=0) fprintf x ;}
|
||
|
# define Tracev(x) {if (verbose>0) fprintf x ;}
|
||
|
# define Tracevv(x) {if (verbose>1) fprintf x ;}
|
||
|
# define Tracec(c,x) {if (verbose>0 && (c)) fprintf x ;}
|
||
|
# define Tracecv(c,x) {if (verbose>1 && (c)) fprintf x ;}
|
||
|
#else
|
||
|
# define Assert(cond,msg)
|
||
|
# define Trace(x)
|
||
|
# define Tracev(x)
|
||
|
# define Tracevv(x)
|
||
|
# define Tracec(c,x)
|
||
|
# define Tracecv(c,x)
|
||
|
#endif
|
||
|
|
||
|
#define MAXBITS 15
|
||
|
#define ENOUGH 2048
|
||
|
#define MAXD 592
|
||
|
|
||
|
typedef struct {
|
||
|
unsigned char op; /* operation, extra bits, table bits */
|
||
|
unsigned char bits; /* bits in this part of the code */
|
||
|
unsigned short val; /* offset in table or code value */
|
||
|
} code;
|
||
|
|
||
|
/* Type of code to build for inftable() */
|
||
|
typedef enum {
|
||
|
CODES,
|
||
|
LENS,
|
||
|
DISTS
|
||
|
} codetype;
|
||
|
|
||
|
/* Possible inflate modes between inflate() calls */
|
||
|
typedef enum {
|
||
|
HEAD, /* i: waiting for magic header */
|
||
|
FLAGS, /* i: waiting for method and flags (gzip) */
|
||
|
TIME, /* i: waiting for modification time (gzip) */
|
||
|
OS, /* i: waiting for extra flags and operating system (gzip) */
|
||
|
EXLEN, /* i: waiting for extra length (gzip) */
|
||
|
EXTRA, /* i: waiting for extra bytes (gzip) */
|
||
|
NAME, /* i: waiting for end of file name (gzip) */
|
||
|
COMMENT, /* i: waiting for end of comment (gzip) */
|
||
|
HCRC, /* i: waiting for header crc (gzip) */
|
||
|
DICTID, /* i: waiting for dictionary check value */
|
||
|
DICT, /* waiting for inflateSetDictionary() call */
|
||
|
TYPE, /* i: waiting for type bits, including last-flag bit */
|
||
|
TYPEDO, /* i: same, but skip check to exit inflate on new block */
|
||
|
STORED, /* i: waiting for stored size (length and complement) */
|
||
|
COPY, /* i/o: waiting for input or output to copy stored block */
|
||
|
TABLE, /* i: waiting for dynamic block table lengths */
|
||
|
LENLENS, /* i: waiting for code length code lengths */
|
||
|
CODELENS, /* i: waiting for length/lit and distance code lengths */
|
||
|
LEN, /* i: waiting for length/lit code */
|
||
|
LENEXT, /* i: waiting for length extra bits */
|
||
|
DIST, /* i: waiting for distance code */
|
||
|
DISTEXT, /* i: waiting for distance extra bits */
|
||
|
MATCH, /* o: waiting for output space to copy string */
|
||
|
LIT, /* o: waiting for output space to write literal */
|
||
|
CHECK, /* i: waiting for 32-bit check value */
|
||
|
LENGTH, /* i: waiting for 32-bit length (gzip) */
|
||
|
DONE, /* finished check, done -- remain here until reset */
|
||
|
ACAB_BAD, /* got a data error -- remain here until reset */
|
||
|
MEM, /* got an inflate() memory error -- remain here until reset */
|
||
|
SYNC /* looking for synchronization bytes to restart inflate() */
|
||
|
} inflate_mode;
|
||
|
|
||
|
/*
|
||
|
State transitions between above modes -
|
||
|
|
||
|
(most modes can go to the BAD or MEM mode -- not shown for clarity)
|
||
|
|
||
|
Process header:
|
||
|
HEAD -> (gzip) or (zlib)
|
||
|
(gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
|
||
|
NAME -> COMMENT -> HCRC -> TYPE
|
||
|
(zlib) -> DICTID or TYPE
|
||
|
DICTID -> DICT -> TYPE
|
||
|
Read deflate blocks:
|
||
|
TYPE -> STORED or TABLE or LEN or CHECK
|
||
|
STORED -> COPY -> TYPE
|
||
|
TABLE -> LENLENS -> CODELENS -> LEN
|
||
|
Read deflate codes:
|
||
|
LEN -> LENEXT or LIT or TYPE
|
||
|
LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
|
||
|
LIT -> LEN
|
||
|
Process trailer:
|
||
|
CHECK -> LENGTH -> DONE
|
||
|
*/
|
||
|
|
||
|
/* state maintained between inflate() calls. Approximately 7K bytes. */
|
||
|
struct inflate_state {
|
||
|
inflate_mode mode; /* current inflate mode */
|
||
|
int last; /* true if processing last block */
|
||
|
int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
|
||
|
int havedict; /* true if dictionary provided */
|
||
|
int flags; /* gzip header method and flags (0 if zlib) */
|
||
|
unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
|
||
|
unsigned long check; /* protected copy of check value */
|
||
|
unsigned long total; /* protected copy of output count */
|
||
|
/* sliding window */
|
||
|
unsigned wbits; /* log base 2 of requested window size */
|
||
|
unsigned wsize; /* window size or zero if not using window */
|
||
|
unsigned whave; /* valid bytes in the window */
|
||
|
unsigned write; /* window write index */
|
||
|
unsigned char FAR *window; /* allocated sliding window, if needed */
|
||
|
/* bit accumulator */
|
||
|
unsigned long hold; /* input bit accumulator */
|
||
|
unsigned bits; /* number of bits in "in" */
|
||
|
/* for string and stored block copying */
|
||
|
unsigned length; /* literal or length of data to copy */
|
||
|
unsigned offset; /* distance back to copy string from */
|
||
|
/* for table and code decoding */
|
||
|
unsigned extra; /* extra bits needed */
|
||
|
/* fixed and dynamic code tables */
|
||
|
code const FAR *lencode; /* starting table for length/literal codes */
|
||
|
code const FAR *distcode; /* starting table for distance codes */
|
||
|
unsigned lenbits; /* index bits for lencode */
|
||
|
unsigned distbits; /* index bits for distcode */
|
||
|
/* dynamic table building */
|
||
|
unsigned ncode; /* number of code length code lengths */
|
||
|
unsigned nlen; /* number of length code lengths */
|
||
|
unsigned ndist; /* number of distance code lengths */
|
||
|
unsigned have; /* number of code lengths in lens[] */
|
||
|
code FAR *next; /* next available space in codes[] */
|
||
|
unsigned short lens[320]; /* temporary storage for code lengths */
|
||
|
unsigned short work[288]; /* work area for code table building */
|
||
|
code codes[ENOUGH]; /* space for code tables */
|
||
|
};
|
||
|
|
||
|
#endif
|