alone_decoder.c 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. ///////////////////////////////////////////////////////////////////////////////
  2. //
  3. /// \file alone_decoder.c
  4. /// \brief Decoder for LZMA_Alone files
  5. //
  6. // Author: Lasse Collin
  7. //
  8. // This file has been put into the public domain.
  9. // You can do whatever you want with this file.
  10. //
  11. ///////////////////////////////////////////////////////////////////////////////
  12. #include "alone_decoder.h"
  13. #include "lzma_decoder.h"
  14. #include "lz_decoder.h"
  15. typedef struct {
  16. lzma_next_coder next;
  17. enum {
  18. SEQ_PROPERTIES,
  19. SEQ_DICTIONARY_SIZE,
  20. SEQ_UNCOMPRESSED_SIZE,
  21. SEQ_CODER_INIT,
  22. SEQ_CODE,
  23. } sequence;
  24. /// If true, reject files that are unlikely to be .lzma files.
  25. /// If false, more non-.lzma files get accepted and will give
  26. /// LZMA_DATA_ERROR either immediately or after a few output bytes.
  27. bool picky;
  28. /// Position in the header fields
  29. size_t pos;
  30. /// Uncompressed size decoded from the header
  31. lzma_vli uncompressed_size;
  32. /// Memory usage limit
  33. uint64_t memlimit;
  34. /// Amount of memory actually needed (only an estimate)
  35. uint64_t memusage;
  36. /// Options decoded from the header needed to initialize
  37. /// the LZMA decoder
  38. lzma_options_lzma options;
  39. } lzma_alone_coder;
  40. static lzma_ret
  41. alone_decode(void *coder_ptr,
  42. const lzma_allocator *allocator lzma_attribute((__unused__)),
  43. const uint8_t *restrict in, size_t *restrict in_pos,
  44. size_t in_size, uint8_t *restrict out,
  45. size_t *restrict out_pos, size_t out_size,
  46. lzma_action action)
  47. {
  48. lzma_alone_coder *coder = coder_ptr;
  49. while (*out_pos < out_size
  50. && (coder->sequence == SEQ_CODE || *in_pos < in_size))
  51. switch (coder->sequence) {
  52. case SEQ_PROPERTIES:
  53. if (lzma_lzma_lclppb_decode(&coder->options, in[*in_pos]))
  54. return LZMA_FORMAT_ERROR;
  55. coder->sequence = SEQ_DICTIONARY_SIZE;
  56. ++*in_pos;
  57. break;
  58. case SEQ_DICTIONARY_SIZE:
  59. coder->options.dict_size
  60. |= (size_t)(in[*in_pos]) << (coder->pos * 8);
  61. if (++coder->pos == 4) {
  62. if (coder->picky && coder->options.dict_size
  63. != UINT32_MAX) {
  64. // A hack to ditch tons of false positives:
  65. // We allow only dictionary sizes that are
  66. // 2^n or 2^n + 2^(n-1). LZMA_Alone created
  67. // only files with 2^n, but accepts any
  68. // dictionary size.
  69. uint32_t d = coder->options.dict_size - 1;
  70. d |= d >> 2;
  71. d |= d >> 3;
  72. d |= d >> 4;
  73. d |= d >> 8;
  74. d |= d >> 16;
  75. ++d;
  76. if (d != coder->options.dict_size)
  77. return LZMA_FORMAT_ERROR;
  78. }
  79. coder->pos = 0;
  80. coder->sequence = SEQ_UNCOMPRESSED_SIZE;
  81. }
  82. ++*in_pos;
  83. break;
  84. case SEQ_UNCOMPRESSED_SIZE:
  85. coder->uncompressed_size
  86. |= (lzma_vli)(in[*in_pos]) << (coder->pos * 8);
  87. ++*in_pos;
  88. if (++coder->pos < 8)
  89. break;
  90. // Another hack to ditch false positives: Assume that
  91. // if the uncompressed size is known, it must be less
  92. // than 256 GiB.
  93. if (coder->picky
  94. && coder->uncompressed_size != LZMA_VLI_UNKNOWN
  95. && coder->uncompressed_size
  96. >= (LZMA_VLI_C(1) << 38))
  97. return LZMA_FORMAT_ERROR;
  98. // Calculate the memory usage so that it is ready
  99. // for SEQ_CODER_INIT.
  100. coder->memusage = lzma_lzma_decoder_memusage(&coder->options)
  101. + LZMA_MEMUSAGE_BASE;
  102. coder->pos = 0;
  103. coder->sequence = SEQ_CODER_INIT;
  104. // Fall through
  105. case SEQ_CODER_INIT: {
  106. if (coder->memusage > coder->memlimit)
  107. return LZMA_MEMLIMIT_ERROR;
  108. lzma_filter_info filters[2] = {
  109. {
  110. .init = &lzma_lzma_decoder_init,
  111. .options = &coder->options,
  112. }, {
  113. .init = NULL,
  114. }
  115. };
  116. const lzma_ret ret = lzma_next_filter_init(&coder->next,
  117. allocator, filters);
  118. if (ret != LZMA_OK)
  119. return ret;
  120. // Use a hack to set the uncompressed size.
  121. lzma_lz_decoder_uncompressed(coder->next.coder,
  122. coder->uncompressed_size);
  123. coder->sequence = SEQ_CODE;
  124. break;
  125. }
  126. case SEQ_CODE: {
  127. return coder->next.code(coder->next.coder,
  128. allocator, in, in_pos, in_size,
  129. out, out_pos, out_size, action);
  130. }
  131. default:
  132. return LZMA_PROG_ERROR;
  133. }
  134. return LZMA_OK;
  135. }
  136. static void
  137. alone_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
  138. {
  139. lzma_alone_coder *coder = coder_ptr;
  140. lzma_next_end(&coder->next, allocator);
  141. lzma_free(coder, allocator);
  142. return;
  143. }
  144. static lzma_ret
  145. alone_decoder_memconfig(void *coder_ptr, uint64_t *memusage,
  146. uint64_t *old_memlimit, uint64_t new_memlimit)
  147. {
  148. lzma_alone_coder *coder = coder_ptr;
  149. *memusage = coder->memusage;
  150. *old_memlimit = coder->memlimit;
  151. if (new_memlimit != 0) {
  152. if (new_memlimit < coder->memusage)
  153. return LZMA_MEMLIMIT_ERROR;
  154. coder->memlimit = new_memlimit;
  155. }
  156. return LZMA_OK;
  157. }
  158. extern lzma_ret
  159. lzma_alone_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator,
  160. uint64_t memlimit, bool picky)
  161. {
  162. lzma_next_coder_init(&lzma_alone_decoder_init, next, allocator);
  163. lzma_alone_coder *coder = next->coder;
  164. if (coder == NULL) {
  165. coder = lzma_alloc(sizeof(lzma_alone_coder), allocator);
  166. if (coder == NULL)
  167. return LZMA_MEM_ERROR;
  168. next->coder = coder;
  169. next->code = &alone_decode;
  170. next->end = &alone_decoder_end;
  171. next->memconfig = &alone_decoder_memconfig;
  172. coder->next = LZMA_NEXT_CODER_INIT;
  173. }
  174. coder->sequence = SEQ_PROPERTIES;
  175. coder->picky = picky;
  176. coder->pos = 0;
  177. coder->options.dict_size = 0;
  178. coder->options.preset_dict = NULL;
  179. coder->options.preset_dict_size = 0;
  180. coder->uncompressed_size = 0;
  181. coder->memlimit = my_max(1, memlimit);
  182. coder->memusage = LZMA_MEMUSAGE_BASE;
  183. return LZMA_OK;
  184. }
  185. extern LZMA_API(lzma_ret)
  186. lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit)
  187. {
  188. lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit, false);
  189. strm->internal->supported_actions[LZMA_RUN] = true;
  190. strm->internal->supported_actions[LZMA_FINISH] = true;
  191. return LZMA_OK;
  192. }