inflate.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345
  1. /* inflate.c -- zlib interface to inflate modules
  2. * Copyright (C) 1995-1996 Mark Adler
  3. * For conditions of distribution and use, see copyright notice in zlib.h
  4. */
  5. #include "zutil.h"
  6. #include "infblock.h"
  7. struct inflate_blocks_state {int dummy;}; /* for buggy compilers */
  8. /* inflate private state */
  9. struct internal_state {
  10. /* mode */
  11. enum {
  12. METHOD, /* waiting for method byte */
  13. FLAG, /* waiting for flag byte */
  14. DICT4, /* four dictionary check bytes to go */
  15. DICT3, /* three dictionary check bytes to go */
  16. DICT2, /* two dictionary check bytes to go */
  17. DICT1, /* one dictionary check byte to go */
  18. DICT0, /* waiting for inflateSetDictionary */
  19. BLOCKS, /* decompressing blocks */
  20. CHECK4, /* four check bytes to go */
  21. CHECK3, /* three check bytes to go */
  22. CHECK2, /* two check bytes to go */
  23. CHECK1, /* one check byte to go */
  24. DONE, /* finished check, done */
  25. BAD} /* got an error--stay here */
  26. mode; /* current inflate mode */
  27. /* mode dependent information */
  28. union {
  29. uInt method; /* if FLAGS, method byte */
  30. struct {
  31. uLong was; /* computed check value */
  32. uLong need; /* stream check value */
  33. } check; /* if CHECK, check values to compare */
  34. uInt marker; /* if BAD, inflateSync's marker bytes count */
  35. } sub; /* submode */
  36. /* mode independent information */
  37. int nowrap; /* flag for no wrapper */
  38. uInt wbits; /* log2(window size) (8..15, defaults to 15) */
  39. inflate_blocks_statef
  40. *blocks; /* current inflate_blocks state */
  41. };
  42. int inflateReset(z)
  43. z_streamp z;
  44. {
  45. uLong c;
  46. if (z == Z_NULL || z->state == Z_NULL)
  47. return Z_STREAM_ERROR;
  48. z->total_in = z->total_out = 0;
  49. z->msg = Z_NULL;
  50. z->state->mode = z->state->nowrap ? BLOCKS : METHOD;
  51. inflate_blocks_reset(z->state->blocks, z, &c);
  52. Trace((stderr, "inflate: reset\n"));
  53. return Z_OK;
  54. }
  55. int inflateEnd(z)
  56. z_streamp z;
  57. {
  58. uLong c;
  59. if (z == Z_NULL || z->state == Z_NULL || z->zfree == Z_NULL)
  60. return Z_STREAM_ERROR;
  61. if (z->state->blocks != Z_NULL)
  62. inflate_blocks_free(z->state->blocks, z, &c);
  63. ZFREE(z, z->state);
  64. z->state = Z_NULL;
  65. Trace((stderr, "inflate: end\n"));
  66. return Z_OK;
  67. }
  68. int inflateInit2_(z, w, version, stream_size)
  69. z_streamp z;
  70. int w;
  71. const char *version;
  72. int stream_size;
  73. {
  74. if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
  75. stream_size != sizeof(z_stream))
  76. return Z_VERSION_ERROR;
  77. /* initialize state */
  78. if (z == Z_NULL)
  79. return Z_STREAM_ERROR;
  80. z->msg = Z_NULL;
  81. if (z->zalloc == Z_NULL)
  82. {
  83. z->zalloc = zcalloc;
  84. z->opaque = (voidpf)0;
  85. }
  86. if (z->zfree == Z_NULL) z->zfree = zcfree;
  87. if ((z->state = (struct internal_state FAR *)
  88. ZALLOC(z,1,sizeof(struct internal_state))) == Z_NULL)
  89. return Z_MEM_ERROR;
  90. z->state->blocks = Z_NULL;
  91. /* handle undocumented nowrap option (no zlib header or check) */
  92. z->state->nowrap = 0;
  93. if (w < 0)
  94. {
  95. w = - w;
  96. z->state->nowrap = 1;
  97. }
  98. /* set window size */
  99. if (w < 8 || w > 15)
  100. {
  101. inflateEnd(z);
  102. return Z_STREAM_ERROR;
  103. }
  104. z->state->wbits = (uInt)w;
  105. /* create inflate_blocks state */
  106. if ((z->state->blocks =
  107. inflate_blocks_new(z, z->state->nowrap ? Z_NULL : adler32, (uInt)1 << w))
  108. == Z_NULL)
  109. {
  110. inflateEnd(z);
  111. return Z_MEM_ERROR;
  112. }
  113. Trace((stderr, "inflate: allocated\n"));
  114. /* reset state */
  115. inflateReset(z);
  116. return Z_OK;
  117. }
  118. int inflateInit_(z, version, stream_size)
  119. z_streamp z;
  120. const char *version;
  121. int stream_size;
  122. {
  123. return inflateInit2_(z, DEF_WBITS, version, stream_size);
  124. }
  125. #define NEEDBYTE {if(z->avail_in==0)return r;r=Z_OK;}
  126. #define NEXTBYTE (z->avail_in--,z->total_in++,*z->next_in++)
  127. int inflate(z, f)
  128. z_streamp z;
  129. int f;
  130. {
  131. int r;
  132. uInt b;
  133. if (z == Z_NULL || z->state == Z_NULL || z->next_in == Z_NULL || f < 0)
  134. return Z_STREAM_ERROR;
  135. r = Z_BUF_ERROR;
  136. while (1) switch (z->state->mode)
  137. {
  138. case METHOD:
  139. NEEDBYTE
  140. if (((z->state->sub.method = NEXTBYTE) & 0xf) != Z_DEFLATED)
  141. {
  142. z->state->mode = BAD;
  143. z->msg = (char*)"unknown compression method";
  144. z->state->sub.marker = 5; /* can't try inflateSync */
  145. break;
  146. }
  147. if ((z->state->sub.method >> 4) + 8 > z->state->wbits)
  148. {
  149. z->state->mode = BAD;
  150. z->msg = (char*)"invalid window size";
  151. z->state->sub.marker = 5; /* can't try inflateSync */
  152. break;
  153. }
  154. z->state->mode = FLAG;
  155. case FLAG:
  156. NEEDBYTE
  157. b = NEXTBYTE;
  158. if (((z->state->sub.method << 8) + b) % 31)
  159. {
  160. z->state->mode = BAD;
  161. z->msg = (char*)"incorrect header check";
  162. z->state->sub.marker = 5; /* can't try inflateSync */
  163. break;
  164. }
  165. Trace((stderr, "inflate: zlib header ok\n"));
  166. if (!(b & PRESET_DICT))
  167. {
  168. z->state->mode = BLOCKS;
  169. break;
  170. }
  171. z->state->mode = DICT4;
  172. case DICT4:
  173. NEEDBYTE
  174. z->state->sub.check.need = (uLong)NEXTBYTE << 24;
  175. z->state->mode = DICT3;
  176. case DICT3:
  177. NEEDBYTE
  178. z->state->sub.check.need += (uLong)NEXTBYTE << 16;
  179. z->state->mode = DICT2;
  180. case DICT2:
  181. NEEDBYTE
  182. z->state->sub.check.need += (uLong)NEXTBYTE << 8;
  183. z->state->mode = DICT1;
  184. case DICT1:
  185. NEEDBYTE
  186. z->state->sub.check.need += (uLong)NEXTBYTE;
  187. z->adler = z->state->sub.check.need;
  188. z->state->mode = DICT0;
  189. return Z_NEED_DICT;
  190. case DICT0:
  191. z->state->mode = BAD;
  192. z->msg = (char*)"need dictionary";
  193. z->state->sub.marker = 0; /* can try inflateSync */
  194. return Z_STREAM_ERROR;
  195. case BLOCKS:
  196. r = inflate_blocks(z->state->blocks, z, r);
  197. if (r == Z_DATA_ERROR)
  198. {
  199. z->state->mode = BAD;
  200. z->state->sub.marker = 0; /* can try inflateSync */
  201. break;
  202. }
  203. if (r != Z_STREAM_END)
  204. return r;
  205. r = Z_OK;
  206. inflate_blocks_reset(z->state->blocks, z, &z->state->sub.check.was);
  207. if (z->state->nowrap)
  208. {
  209. z->state->mode = DONE;
  210. break;
  211. }
  212. z->state->mode = CHECK4;
  213. case CHECK4:
  214. NEEDBYTE
  215. z->state->sub.check.need = (uLong)NEXTBYTE << 24;
  216. z->state->mode = CHECK3;
  217. case CHECK3:
  218. NEEDBYTE
  219. z->state->sub.check.need += (uLong)NEXTBYTE << 16;
  220. z->state->mode = CHECK2;
  221. case CHECK2:
  222. NEEDBYTE
  223. z->state->sub.check.need += (uLong)NEXTBYTE << 8;
  224. z->state->mode = CHECK1;
  225. case CHECK1:
  226. NEEDBYTE
  227. z->state->sub.check.need += (uLong)NEXTBYTE;
  228. if (z->state->sub.check.was != z->state->sub.check.need)
  229. {
  230. z->state->mode = BAD;
  231. z->msg = (char*)"incorrect data check";
  232. z->state->sub.marker = 5; /* can't try inflateSync */
  233. break;
  234. }
  235. Trace((stderr, "inflate: zlib check ok\n"));
  236. z->state->mode = DONE;
  237. case DONE:
  238. return Z_STREAM_END;
  239. case BAD:
  240. return Z_DATA_ERROR;
  241. default:
  242. return Z_STREAM_ERROR;
  243. }
  244. }
  245. int inflateSetDictionary(z, dictionary, dictLength)
  246. z_streamp z;
  247. const Bytef *dictionary;
  248. uInt dictLength;
  249. {
  250. uInt length = dictLength;
  251. if (z == Z_NULL || z->state == Z_NULL || z->state->mode != DICT0)
  252. return Z_STREAM_ERROR;
  253. if (adler32(1L, dictionary, dictLength) != z->adler) return Z_DATA_ERROR;
  254. z->adler = 1L;
  255. if (length >= ((uInt)1<<z->state->wbits))
  256. {
  257. length = (1<<z->state->wbits)-1;
  258. dictionary += dictLength - length;
  259. }
  260. inflate_set_dictionary(z->state->blocks, dictionary, length);
  261. z->state->mode = BLOCKS;
  262. return Z_OK;
  263. }
  264. int inflateSync(z)
  265. z_streamp z;
  266. {
  267. uInt n; /* number of bytes to look at */
  268. Bytef *p; /* pointer to bytes */
  269. uInt m; /* number of marker bytes found in a row */
  270. uLong r, w; /* temporaries to save total_in and total_out */
  271. /* set up */
  272. if (z == Z_NULL || z->state == Z_NULL)
  273. return Z_STREAM_ERROR;
  274. if (z->state->mode != BAD)
  275. {
  276. z->state->mode = BAD;
  277. z->state->sub.marker = 0;
  278. }
  279. if ((n = z->avail_in) == 0)
  280. return Z_BUF_ERROR;
  281. p = z->next_in;
  282. m = z->state->sub.marker;
  283. /* search */
  284. while (n && m < 4)
  285. {
  286. if (*p == (Byte)(m < 2 ? 0 : 0xff))
  287. m++;
  288. else if (*p)
  289. m = 0;
  290. else
  291. m = 4 - m;
  292. p++, n--;
  293. }
  294. /* restore */
  295. z->total_in += p - z->next_in;
  296. z->next_in = p;
  297. z->avail_in = n;
  298. z->state->sub.marker = m;
  299. /* return no joy or set up to restart on a new block */
  300. if (m != 4)
  301. return Z_DATA_ERROR;
  302. r = z->total_in; w = z->total_out;
  303. inflateReset(z);
  304. z->total_in = r; z->total_out = w;
  305. z->state->mode = BLOCKS;
  306. return Z_OK;
  307. }