alone_decoder.c 5.9 KB

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