decompress_uncompress.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293
  1. #include "config.h"
  2. #include "libbb.h"
  3. /* uncompress for busybox -- (c) 2002 Robert Griebl
  4. *
  5. * based on the original compress42.c source
  6. * (see disclaimer below)
  7. */
  8. /* (N)compress42.c - File compression ala IEEE Computer, Mar 1992.
  9. *
  10. * Authors:
  11. * Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)
  12. * Jim McKie (decvax!mcvax!jim)
  13. * Steve Davies (decvax!vax135!petsd!peora!srd)
  14. * Ken Turkowski (decvax!decwrl!turtlevax!ken)
  15. * James A. Woods (decvax!ihnp4!ames!jaw)
  16. * Joe Orost (decvax!vax135!petsd!joe)
  17. * Dave Mack (csu@alembic.acs.com)
  18. * Peter Jannesen, Network Communication Systems
  19. * (peter@ncs.nl)
  20. *
  21. * marc@suse.de : a small security fix for a buffer overflow
  22. *
  23. * [... History snipped ...]
  24. *
  25. */
  26. #include <stdio.h>
  27. #include <string.h>
  28. #include <unistd.h>
  29. /* Default input buffer size */
  30. #define IBUFSIZ 2048
  31. /* Default output buffer size */
  32. #define OBUFSIZ 2048
  33. /* Defines for third byte of header */
  34. #define MAGIC_1 (char_type)'\037' /* First byte of compressed file */
  35. #define MAGIC_2 (char_type)'\235' /* Second byte of compressed file */
  36. #define BIT_MASK 0x1f /* Mask for 'number of compresssion bits' */
  37. /* Masks 0x20 and 0x40 are free. */
  38. /* I think 0x20 should mean that there is */
  39. /* a fourth header byte (for expansion). */
  40. #define BLOCK_MODE 0x80 /* Block compresssion if table is full and */
  41. /* compression rate is dropping flush tables */
  42. /* the next two codes should not be changed lightly, as they must not */
  43. /* lie within the contiguous general code space. */
  44. #define FIRST 257 /* first free entry */
  45. #define CLEAR 256 /* table clear output code */
  46. #define INIT_BITS 9 /* initial number of bits/code */
  47. /* machine variants which require cc -Dmachine: pdp11, z8000, DOS */
  48. #define FAST
  49. #define HBITS 17 /* 50% occupancy */
  50. #define HSIZE (1<<HBITS)
  51. #define HMASK (HSIZE-1)
  52. #define HPRIME 9941
  53. #define BITS 16
  54. #undef MAXSEG_64K
  55. #define MAXCODE(n) (1L << (n))
  56. /* Block compress mode -C compatible with 2.0 */
  57. static int block_mode = BLOCK_MODE;
  58. /* user settable max # bits/code */
  59. static int maxbits = BITS;
  60. /* Exitcode of compress (-1 no file compressed) */
  61. static int exit_code = -1;
  62. /* Input buffer */
  63. static unsigned char inbuf[IBUFSIZ + 64];
  64. /* Output buffer */
  65. static unsigned char outbuf[OBUFSIZ + 2048];
  66. static long int htab[HSIZE];
  67. static unsigned short codetab[HSIZE];
  68. #define htabof(i) htab[i]
  69. #define codetabof(i) codetab[i]
  70. #define tab_prefixof(i) codetabof(i)
  71. #define tab_suffixof(i) ((unsigned char *)(htab))[i]
  72. #define de_stack ((unsigned char *)&(htab[HSIZE-1]))
  73. #define clear_htab() memset(htab, -1, sizeof(htab))
  74. #define clear_tab_prefixof() memset(codetab, 0, 256);
  75. /*
  76. * Decompress stdin to stdout. This routine adapts to the codes in the
  77. * file building the "string" table on-the-fly; requiring no table to
  78. * be stored in the compressed file. The tables used herein are shared
  79. * with those of the compress() routine. See the definitions above.
  80. */
  81. extern int uncompress(int fd_in, int fd_out)
  82. {
  83. unsigned char *stackp;
  84. long int code;
  85. int finchar;
  86. long int oldcode;
  87. long int incode;
  88. int inbits;
  89. int posbits;
  90. int outpos;
  91. int insize;
  92. int bitmask;
  93. long int free_ent;
  94. long int maxcode;
  95. long int maxmaxcode;
  96. int n_bits;
  97. int rsize = 0;
  98. insize = 0;
  99. inbuf[0] = bb_xread_char(fd_in);
  100. maxbits = inbuf[0] & BIT_MASK;
  101. block_mode = inbuf[0] & BLOCK_MODE;
  102. maxmaxcode = MAXCODE(maxbits);
  103. if (maxbits > BITS) {
  104. bb_error_msg("compressed with %d bits, can only handle %d bits", maxbits,
  105. BITS);
  106. return -1;
  107. }
  108. maxcode = MAXCODE(n_bits = INIT_BITS) - 1;
  109. bitmask = (1 << n_bits) - 1;
  110. oldcode = -1;
  111. finchar = 0;
  112. outpos = 0;
  113. posbits = 0 << 3;
  114. free_ent = ((block_mode) ? FIRST : 256);
  115. /* As above, initialize the first 256 entries in the table. */
  116. clear_tab_prefixof();
  117. for (code = 255; code >= 0; --code) {
  118. tab_suffixof(code) = (unsigned char) code;
  119. }
  120. do {
  121. resetbuf:;
  122. {
  123. int i;
  124. int e;
  125. int o;
  126. e = insize - (o = (posbits >> 3));
  127. for (i = 0; i < e; ++i)
  128. inbuf[i] = inbuf[i + o];
  129. insize = e;
  130. posbits = 0;
  131. }
  132. if (insize < (int) sizeof(inbuf) - IBUFSIZ) {
  133. rsize = safe_read(fd_in, inbuf + insize, IBUFSIZ);
  134. insize += rsize;
  135. }
  136. inbits = ((rsize > 0) ? (insize - insize % n_bits) << 3 :
  137. (insize << 3) - (n_bits - 1));
  138. while (inbits > posbits) {
  139. if (free_ent > maxcode) {
  140. posbits =
  141. ((posbits - 1) +
  142. ((n_bits << 3) -
  143. (posbits - 1 + (n_bits << 3)) % (n_bits << 3)));
  144. ++n_bits;
  145. if (n_bits == maxbits) {
  146. maxcode = maxmaxcode;
  147. } else {
  148. maxcode = MAXCODE(n_bits) - 1;
  149. }
  150. bitmask = (1 << n_bits) - 1;
  151. goto resetbuf;
  152. }
  153. {
  154. unsigned char *p = &inbuf[posbits >> 3];
  155. code =
  156. ((((long) (p[0])) | ((long) (p[1]) << 8) |
  157. ((long) (p[2]) << 16)) >> (posbits & 0x7)) & bitmask;
  158. }
  159. posbits += n_bits;
  160. if (oldcode == -1) {
  161. outbuf[outpos++] = (unsigned char) (finchar =
  162. (int) (oldcode = code));
  163. continue;
  164. }
  165. if (code == CLEAR && block_mode) {
  166. clear_tab_prefixof();
  167. free_ent = FIRST - 1;
  168. posbits =
  169. ((posbits - 1) +
  170. ((n_bits << 3) -
  171. (posbits - 1 + (n_bits << 3)) % (n_bits << 3)));
  172. maxcode = MAXCODE(n_bits = INIT_BITS) - 1;
  173. bitmask = (1 << n_bits) - 1;
  174. goto resetbuf;
  175. }
  176. incode = code;
  177. stackp = de_stack;
  178. /* Special case for KwKwK string. */
  179. if (code >= free_ent) {
  180. if (code > free_ent) {
  181. unsigned char *p;
  182. posbits -= n_bits;
  183. p = &inbuf[posbits >> 3];
  184. bb_error_msg
  185. ("insize:%d posbits:%d inbuf:%02X %02X %02X %02X %02X (%d)",
  186. insize, posbits, p[-1], p[0], p[1], p[2], p[3],
  187. (posbits & 07));
  188. bb_error_msg("uncompress: corrupt input");
  189. return -1;
  190. }
  191. *--stackp = (unsigned char) finchar;
  192. code = oldcode;
  193. }
  194. /* Generate output characters in reverse order */
  195. while ((long int) code >= (long int) 256) {
  196. *--stackp = tab_suffixof(code);
  197. code = tab_prefixof(code);
  198. }
  199. *--stackp = (unsigned char) (finchar = tab_suffixof(code));
  200. /* And put them out in forward order */
  201. {
  202. int i;
  203. if (outpos + (i = (de_stack - stackp)) >= OBUFSIZ) {
  204. do {
  205. if (i > OBUFSIZ - outpos) {
  206. i = OBUFSIZ - outpos;
  207. }
  208. if (i > 0) {
  209. memcpy(outbuf + outpos, stackp, i);
  210. outpos += i;
  211. }
  212. if (outpos >= OBUFSIZ) {
  213. write(fd_out, outbuf, outpos);
  214. outpos = 0;
  215. }
  216. stackp += i;
  217. } while ((i = (de_stack - stackp)) > 0);
  218. } else {
  219. memcpy(outbuf + outpos, stackp, i);
  220. outpos += i;
  221. }
  222. }
  223. /* Generate the new entry. */
  224. if ((code = free_ent) < maxmaxcode) {
  225. tab_prefixof(code) = (unsigned short) oldcode;
  226. tab_suffixof(code) = (unsigned char) finchar;
  227. free_ent = code + 1;
  228. }
  229. /* Remember previous code. */
  230. oldcode = incode;
  231. }
  232. } while (rsize > 0);
  233. if (outpos > 0) {
  234. write(fd_out, outbuf, outpos);
  235. }
  236. return 0;
  237. }