inflate_p.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231
  1. /* inflate_p.h -- Private inline functions and macros shared with more than one deflate method
  2. *
  3. */
  4. #ifndef INFLATE_P_H
  5. #define INFLATE_P_H
  6. #include <stdlib.h>
  7. /* Architecture-specific hooks. */
  8. #ifdef S390_DFLTCC_INFLATE
  9. # include "arch/s390/dfltcc_inflate.h"
  10. /* DFLTCC instructions require window to be page-aligned */
  11. # define PAD_WINDOW PAD_4096
  12. # define WINDOW_PAD_SIZE 4096
  13. # define HINT_ALIGNED_WINDOW HINT_ALIGNED_4096
  14. #else
  15. # define PAD_WINDOW PAD_64
  16. # define WINDOW_PAD_SIZE 64
  17. # define HINT_ALIGNED_WINDOW HINT_ALIGNED_64
  18. /* Adjust the window size for the arch-specific inflate code. */
  19. # define INFLATE_ADJUST_WINDOW_SIZE(n) (n)
  20. /* Invoked at the end of inflateResetKeep(). Useful for initializing arch-specific extension blocks. */
  21. # define INFLATE_RESET_KEEP_HOOK(strm) do {} while (0)
  22. /* Invoked at the beginning of inflatePrime(). Useful for updating arch-specific buffers. */
  23. # define INFLATE_PRIME_HOOK(strm, bits, value) do {} while (0)
  24. /* Invoked at the beginning of each block. Useful for plugging arch-specific inflation code. */
  25. # define INFLATE_TYPEDO_HOOK(strm, flush) do {} while (0)
  26. /* Returns whether zlib-ng should compute a checksum. Set to 0 if arch-specific inflation code already does that. */
  27. # define INFLATE_NEED_CHECKSUM(strm) 1
  28. /* Returns whether zlib-ng should update a window. Set to 0 if arch-specific inflation code already does that. */
  29. # define INFLATE_NEED_UPDATEWINDOW(strm) 1
  30. /* Invoked at the beginning of inflateMark(). Useful for updating arch-specific pointers and offsets. */
  31. # define INFLATE_MARK_HOOK(strm) do {} while (0)
  32. /* Invoked at the beginning of inflateSyncPoint(). Useful for performing arch-specific state checks. */
  33. # define INFLATE_SYNC_POINT_HOOK(strm) do {} while (0)
  34. /* Invoked at the beginning of inflateSetDictionary(). Useful for checking arch-specific window data. */
  35. # define INFLATE_SET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
  36. /* Invoked at the beginning of inflateGetDictionary(). Useful for adjusting arch-specific window data. */
  37. # define INFLATE_GET_DICTIONARY_HOOK(strm, dict, dict_len) do {} while (0)
  38. #endif
  39. /*
  40. * Macros shared by inflate() and inflateBack()
  41. */
  42. /* check function to use adler32() for zlib or crc32() for gzip */
  43. #ifdef GUNZIP
  44. # define UPDATE(check, buf, len) \
  45. (state->flags ? PREFIX(crc32)(check, buf, len) : FUNCTABLE_CALL(adler32)(check, buf, len))
  46. #else
  47. # define UPDATE(check, buf, len) FUNCTABLE_CALL(adler32)(check, buf, len)
  48. #endif
  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. # define CRC4(check, word) \
  58. do { \
  59. hbuf[0] = (unsigned char)(word); \
  60. hbuf[1] = (unsigned char)((word) >> 8); \
  61. hbuf[2] = (unsigned char)((word) >> 16); \
  62. hbuf[3] = (unsigned char)((word) >> 24); \
  63. check = PREFIX(crc32)(check, hbuf, 4); \
  64. } while (0)
  65. #endif
  66. /* Load registers with state in inflate() for speed */
  67. #define LOAD() \
  68. do { \
  69. put = strm->next_out; \
  70. left = strm->avail_out; \
  71. next = strm->next_in; \
  72. have = strm->avail_in; \
  73. hold = state->hold; \
  74. bits = state->bits; \
  75. } while (0)
  76. /* Restore state from registers in inflate() */
  77. #define RESTORE() \
  78. do { \
  79. strm->next_out = put; \
  80. strm->avail_out = left; \
  81. strm->next_in = (z_const unsigned char *)next; \
  82. strm->avail_in = have; \
  83. state->hold = hold; \
  84. state->bits = bits; \
  85. } while (0)
  86. /* Clear the input bit accumulator */
  87. #define INITBITS() \
  88. do { \
  89. hold = 0; \
  90. bits = 0; \
  91. } while (0)
  92. /* Ensure that there is at least n bits in the bit accumulator. If there is
  93. not enough available input to do that, then return from inflate()/inflateBack(). */
  94. #define NEEDBITS(n) \
  95. do { \
  96. while (bits < (unsigned)(n)) \
  97. PULLBYTE(); \
  98. } while (0)
  99. /* Return the low n bits of the bit accumulator (n < 16) */
  100. #define BITS(n) \
  101. (hold & ((1U << (unsigned)(n)) - 1))
  102. /* Remove n bits from the bit accumulator */
  103. #define DROPBITS(n) \
  104. do { \
  105. hold >>= (n); \
  106. bits -= (unsigned)(n); \
  107. } while (0)
  108. /* Remove zero to seven bits as needed to go to a byte boundary */
  109. #define BYTEBITS() \
  110. do { \
  111. hold >>= bits & 7; \
  112. bits -= bits & 7; \
  113. } while (0)
  114. /* Set mode=BAD and prepare error message */
  115. #define SET_BAD(errmsg) \
  116. do { \
  117. state->mode = BAD; \
  118. strm->msg = (char *)errmsg; \
  119. } while (0)
  120. #define INFLATE_FAST_MIN_HAVE 15
  121. #define INFLATE_FAST_MIN_LEFT 260
  122. /* Load 64 bits from IN and place the bytes at offset BITS in the result. */
  123. static inline uint64_t load_64_bits(const unsigned char *in, unsigned bits) {
  124. uint64_t chunk;
  125. memcpy(&chunk, in, sizeof(chunk));
  126. #if BYTE_ORDER == LITTLE_ENDIAN
  127. return chunk << bits;
  128. #else
  129. return ZSWAP64(chunk) << bits;
  130. #endif
  131. }
  132. /* Behave like chunkcopy, but avoid writing beyond of legal output. */
  133. static inline uint8_t* chunkcopy_safe(uint8_t *out, uint8_t *from, uint64_t len, uint8_t *safe) {
  134. uint64_t safelen = (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. uint64_t tocopy;
  139. /* For all cases without overlap, memcpy is ideal */
  140. if (!(olap_src || olap_dst)) {
  141. memcpy(out, from, (size_t)len);
  142. return out + len;
  143. }
  144. /* Complete overlap: Source == destination */
  145. if (out == from) {
  146. return out + len;
  147. }
  148. /* We are emulating a self-modifying copy loop here. To do this in a way that doesn't produce undefined behavior,
  149. * 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
  150. * initial bulk memcpy of the nonoverlapping region. Then, we can leverage the size of this to determine the safest
  151. * atomic memcpy size we can pick such that we have non-overlapping regions. This effectively becomes a safe look
  152. * behind or lookahead distance. */
  153. uint64_t non_olap_size = llabs(from - out); // llabs vs labs for compatibility with windows
  154. memcpy(out, from, (size_t)non_olap_size);
  155. out += non_olap_size;
  156. from += non_olap_size;
  157. len -= non_olap_size;
  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. while (tocopy >= 32) {
  164. memcpy(out, from, 32);
  165. out += 32;
  166. from += 32;
  167. tocopy -= 32;
  168. }
  169. if (tocopy >= 16) {
  170. memcpy(out, from, 16);
  171. out += 16;
  172. from += 16;
  173. tocopy -= 16;
  174. }
  175. if (tocopy >= 8) {
  176. memcpy(out, from, 8);
  177. out += 8;
  178. from += 8;
  179. tocopy -= 8;
  180. }
  181. if (tocopy >= 4) {
  182. memcpy(out, from, 4);
  183. out += 4;
  184. from += 4;
  185. tocopy -= 4;
  186. }
  187. if (tocopy >= 2) {
  188. memcpy(out, from, 2);
  189. out += 2;
  190. from += 2;
  191. tocopy -= 2;
  192. }
  193. if (tocopy) {
  194. *out++ = *from++;
  195. }
  196. }
  197. return out;
  198. }
  199. #endif