1 /* inflate_p.h -- Private inline functions and macros shared with more than one deflate method
2  *
3  */
4 
5 #ifndef INFLATE_P_H
6 #define INFLATE_P_H
7 
8 #include <stdlib.h>
9 
10 /* Architecture-specific hooks. */
11 #ifdef S390_DFLTCC_INFLATE
12 #  include "arch/s390/dfltcc_inflate.h"
13 #else
14 /* Memory management for the inflate state. Useful for allocating arch-specific extension blocks. */
15 #  define ZALLOC_INFLATE_STATE(strm) ((struct inflate_state *)ZALLOC(strm, 1, sizeof(struct inflate_state)))
16 #  define ZFREE_STATE(strm, addr) ZFREE(strm, addr)
17 #  define ZCOPY_INFLATE_STATE(dst, src) memcpy(dst, src, sizeof(struct inflate_state))
18 /* Memory management for the window. Useful for allocation the aligned window. */
19 #  define ZALLOC_WINDOW(strm, items, size) ZALLOC(strm, items, size)
20 #  define ZFREE_WINDOW(strm, addr) ZFREE(strm, addr)
21 /* Invoked at the end of inflateResetKeep(). Useful for initializing arch-specific extension blocks. */
22 #  define INFLATE_RESET_KEEP_HOOK(strm) do {} while (0)
23 /* Invoked at the beginning of inflatePrime(). Useful for updating arch-specific buffers. */
24 #  define INFLATE_PRIME_HOOK(strm, bits, value) do {} while (0)
25 /* Invoked at the beginning of each block. Useful for plugging arch-specific inflation code. */
26 #  define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0)
27 /* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific inflation code already does that. */
28 #  define INFLATE_NEED_CHECKSUM(strm) 1
29 /* Returns whether zlib-ng should update a window. Set to 0 if arch-specific inflation code already does that. */
30 #  define INFLATE_NEED_UPDATEWINDOW(strm) 1
31 /* Invoked at the beginning of inflateMark(). Useful for updating arch-specific pointers and offsets. */
32 #  define INFLATE_MARK_HOOK(strm) do {} while (0)
33 /* Invoked at the beginning of inflateSyncPoint(). Useful for performing arch-specific state checks. */
34 #  define INFLATE_SYNC_POINT_HOOK(strm) do {} while (0)
35 #endif
36 
37 /*
38  *   Macros shared by inflate() and inflateBack()
39  */
40 
41 /* check function to use adler32() for zlib or crc32() for gzip */
42 #ifdef GUNZIP
43 #  define UPDATE(check, buf, len) \
44     (state->flags ? PREFIX(crc32)(check, buf, len) : functable.adler32(check, buf, len))
45 #else
46 #  define UPDATE(check, buf, len) functable.adler32(check, buf, len)
47 #endif
48 
49 /* check macros for header crc */
50 #ifdef GUNZIP
51 #  define CRC2(check, word) \
52     do { \
53         hbuf[0] = (unsigned char)(word); \
54         hbuf[1] = (unsigned char)((word) >> 8); \
55         check = PREFIX(crc32)(check, hbuf, 2); \
56     } while (0)
57 
58 #  define CRC4(check, word) \
59     do { \
60         hbuf[0] = (unsigned char)(word); \
61         hbuf[1] = (unsigned char)((word) >> 8); \
62         hbuf[2] = (unsigned char)((word) >> 16); \
63         hbuf[3] = (unsigned char)((word) >> 24); \
64         check = PREFIX(crc32)(check, hbuf, 4); \
65     } while (0)
66 #endif
67 
68 /* Load registers with state in inflate() for speed */
69 #define LOAD() \
70     do { \
71         put = strm->next_out; \
72         left = strm->avail_out; \
73         next = strm->next_in; \
74         have = strm->avail_in; \
75         hold = state->hold; \
76         bits = state->bits; \
77     } while (0)
78 
79 /* Restore state from registers in inflate() */
80 #define RESTORE() \
81     do { \
82         strm->next_out = put; \
83         strm->avail_out = left; \
84         strm->next_in = (z_const unsigned char *)next; \
85         strm->avail_in = have; \
86         state->hold = hold; \
87         state->bits = bits; \
88     } while (0)
89 
90 /* Clear the input bit accumulator */
91 #define INITBITS() \
92     do { \
93         hold = 0; \
94         bits = 0; \
95     } while (0)
96 
97 /* Ensure that there is at least n bits in the bit accumulator.  If there is
98    not enough available input to do that, then return from inflate()/inflateBack(). */
99 #define NEEDBITS(n) \
100     do { \
101         while (bits < (unsigned)(n)) \
102             PULLBYTE(); \
103     } while (0)
104 
105 /* Return the low n bits of the bit accumulator (n < 16) */
106 #define BITS(n) \
107     (hold & ((1U << (unsigned)(n)) - 1))
108 
109 /* Remove n bits from the bit accumulator */
110 #define DROPBITS(n) \
111     do { \
112         hold >>= (n); \
113         bits -= (unsigned)(n); \
114     } while (0)
115 
116 /* Remove zero to seven bits as needed to go to a byte boundary */
117 #define BYTEBITS() \
118     do { \
119         hold >>= bits & 7; \
120         bits -= bits & 7; \
121     } while (0)
122 
123 #endif
124 
125 /* Set mode=BAD and prepare error message */
126 #define SET_BAD(errmsg) \
127     do { \
128         state->mode = BAD; \
129         strm->msg = (char *)errmsg; \
130     } while (0)
131 
132 /* Behave like chunkcopy, but avoid writing beyond of legal output. */
chunkcopy_safe(uint8_t * out,uint8_t * from,size_t len,uint8_t * safe)133 static inline uint8_t* chunkcopy_safe(uint8_t *out, uint8_t *from, size_t len, uint8_t *safe) {
134     uint32_t safelen = (uint32_t)((safe - out) + 1);
135     len = MIN(len, safelen);
136     int32_t olap_src = from >= out && from < out + len;
137     int32_t olap_dst = out >= from && out < from + len;
138     size_t tocopy;
139 
140     /* For all cases without overlap, memcpy is ideal */
141     if (!(olap_src || olap_dst)) {
142         memcpy(out, from, len);
143         return out + len;
144     }
145 
146     /* We are emulating a self-modifying copy loop here. To do this in a way that doesn't produce undefined behavior,
147      * we have to get a bit clever. First if the overlap is such that src falls between dst and dst+len, we can do the
148      * initial bulk memcpy of the nonoverlapping region. Then, we can leverage the size of this to determine the safest
149      * atomic memcpy size we can pick such that we have non-overlapping regions. This effectively becomes a safe look
150      * behind or lookahead distance. */
151     size_t non_olap_size = llabs(from - out); // llabs vs labs for compatibility with windows
152 
153     memcpy(out, from, non_olap_size);
154     out += non_olap_size;
155     from += non_olap_size;
156     len -= non_olap_size;
157 
158     /* So this doesn't give use a worst case scenario of function calls in a loop,
159      * we want to instead break this down into copy blocks of fixed lengths */
160     while (len) {
161         tocopy = MIN(non_olap_size, len);
162         len -= tocopy;
163 
164         while (tocopy >= 32) {
165             memcpy(out, from, 32);
166             out += 32;
167             from += 32;
168             tocopy -= 32;
169         }
170 
171         if (tocopy >= 16) {
172             memcpy(out, from, 16);
173             out += 16;
174             from += 16;
175             tocopy -= 16;
176         }
177 
178         if (tocopy >= 8) {
179             zmemcpy_8(out, from);
180             out += 8;
181             from += 8;
182             tocopy -= 8;
183         }
184 
185         if (tocopy >= 4) {
186             zmemcpy_4(out, from);
187             out += 4;
188             from += 4;
189             tocopy -= 4;
190         }
191 
192         if (tocopy >= 2) {
193             zmemcpy_2(out, from);
194             out += 2;
195             from += 2;
196             tocopy -= 2;
197         }
198 
199         if (tocopy) {
200             *out++ = *from++;
201         }
202     }
203 
204     return out;
205 }
206