Rizin
unix-like reverse engineering framework and cli tools
alone_decoder.c
Go to the documentation of this file.
1 //
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 //
12 
13 #include "alone_decoder.h"
14 #include "lzma_decoder.h"
15 #include "lz_decoder.h"
16 
17 
18 typedef struct {
20 
21  enum {
27  } sequence;
28 
32  bool picky;
33 
35  size_t pos;
36 
39 
42 
45 
50 
51 
52 static lzma_ret
53 alone_decode(void *coder_ptr, const lzma_allocator *allocator,
54  const uint8_t *restrict in, size_t *restrict in_pos,
55  size_t in_size, uint8_t *restrict out,
56  size_t *restrict out_pos, size_t out_size,
58 {
59  lzma_alone_coder *coder = coder_ptr;
60 
61  while (*out_pos < out_size
62  && (coder->sequence == SEQ_CODE || *in_pos < in_size))
63  switch (coder->sequence) {
64  case SEQ_PROPERTIES:
65  if (lzma_lzma_lclppb_decode(&coder->options, in[*in_pos]))
66  return LZMA_FORMAT_ERROR;
67 
68  coder->sequence = SEQ_DICTIONARY_SIZE;
69  ++*in_pos;
70  break;
71 
72  case SEQ_DICTIONARY_SIZE:
73  coder->options.dict_size
74  |= (size_t)(in[*in_pos]) << (coder->pos * 8);
75 
76  if (++coder->pos == 4) {
77  if (coder->picky && coder->options.dict_size
78  != UINT32_MAX) {
79  // A hack to ditch tons of false positives:
80  // We allow only dictionary sizes that are
81  // 2^n or 2^n + 2^(n-1). LZMA_Alone created
82  // only files with 2^n, but accepts any
83  // dictionary size.
84  uint32_t d = coder->options.dict_size - 1;
85  d |= d >> 2;
86  d |= d >> 3;
87  d |= d >> 4;
88  d |= d >> 8;
89  d |= d >> 16;
90  ++d;
91 
92  if (d != coder->options.dict_size)
93  return LZMA_FORMAT_ERROR;
94  }
95 
96  coder->pos = 0;
97  coder->sequence = SEQ_UNCOMPRESSED_SIZE;
98  }
99 
100  ++*in_pos;
101  break;
102 
103  case SEQ_UNCOMPRESSED_SIZE:
104  coder->uncompressed_size
105  |= (lzma_vli)(in[*in_pos]) << (coder->pos * 8);
106  ++*in_pos;
107  if (++coder->pos < 8)
108  break;
109 
110  // Another hack to ditch false positives: Assume that
111  // if the uncompressed size is known, it must be less
112  // than 256 GiB.
113  if (coder->picky
115  && coder->uncompressed_size
116  >= (LZMA_VLI_C(1) << 38))
117  return LZMA_FORMAT_ERROR;
118 
119  // Calculate the memory usage so that it is ready
120  // for SEQ_CODER_INIT.
123 
124  coder->pos = 0;
125  coder->sequence = SEQ_CODER_INIT;
126 
127  // Fall through
128 
129  case SEQ_CODER_INIT: {
130  if (coder->memusage > coder->memlimit)
131  return LZMA_MEMLIMIT_ERROR;
132 
134  {
135  .init = &lzma_lzma_decoder_init,
136  .options = &coder->options,
137  }, {
138  .init = NULL,
139  }
140  };
141 
142  const lzma_ret ret = lzma_next_filter_init(&coder->next,
143  allocator, filters);
144  if (ret != LZMA_OK)
145  return ret;
146 
147  // Use a hack to set the uncompressed size.
149  coder->uncompressed_size);
150 
151  coder->sequence = SEQ_CODE;
152  break;
153  }
154 
155  case SEQ_CODE: {
156  return coder->next.code(coder->next.coder,
158  out, out_pos, out_size, action);
159  }
160 
161  default:
162  return LZMA_PROG_ERROR;
163  }
164 
165  return LZMA_OK;
166 }
167 
168 
169 static void
171 {
172  lzma_alone_coder *coder = coder_ptr;
173  lzma_next_end(&coder->next, allocator);
174  lzma_free(coder, allocator);
175  return;
176 }
177 
178 
179 static lzma_ret
180 alone_decoder_memconfig(void *coder_ptr, uint64_t *memusage,
181  uint64_t *old_memlimit, uint64_t new_memlimit)
182 {
183  lzma_alone_coder *coder = coder_ptr;
184 
185  *memusage = coder->memusage;
186  *old_memlimit = coder->memlimit;
187 
188  if (new_memlimit != 0) {
189  if (new_memlimit < coder->memusage)
190  return LZMA_MEMLIMIT_ERROR;
191 
192  coder->memlimit = new_memlimit;
193  }
194 
195  return LZMA_OK;
196 }
197 
198 
199 extern lzma_ret
201  uint64_t memlimit, bool picky)
202 {
204 
205  lzma_alone_coder *coder = next->coder;
206 
207  if (coder == NULL) {
208  coder = lzma_alloc(sizeof(lzma_alone_coder), allocator);
209  if (coder == NULL)
210  return LZMA_MEM_ERROR;
211 
212  next->coder = coder;
213  next->code = &alone_decode;
214  next->end = &alone_decoder_end;
216  coder->next = LZMA_NEXT_CODER_INIT;
217  }
218 
219  coder->sequence = SEQ_PROPERTIES;
220  coder->picky = picky;
221  coder->pos = 0;
222  coder->options.dict_size = 0;
223  coder->options.preset_dict = NULL;
224  coder->options.preset_dict_size = 0;
225  coder->uncompressed_size = 0;
226  coder->memlimit = my_max(1, memlimit);
227  coder->memusage = LZMA_MEMUSAGE_BASE;
228 
229  return LZMA_OK;
230 }
231 
232 
234 lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit)
235 {
237 
240 
241  return LZMA_OK;
242 }
LZMA_API(lzma_ret)
static lzma_ret alone_decoder_memconfig(void *coder_ptr, uint64_t *memusage, uint64_t *old_memlimit, uint64_t new_memlimit)
static void alone_decoder_end(void *coder_ptr, const lzma_allocator *allocator)
static lzma_ret alone_decode(void *coder_ptr, const lzma_allocator *allocator, const uint8_t *restrict in, size_t *restrict in_pos, size_t in_size, uint8_t *restrict out, size_t *restrict out_pos, size_t out_size, lzma_action action)
Definition: alone_decoder.c:53
lzma_ret lzma_alone_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, uint64_t memlimit, bool picky)
Decoder for LZMA_Alone files.
const lzma_allocator const uint8_t size_t uint8_t size_t * out_pos
Definition: block.h:528
const lzma_allocator const uint8_t size_t * in_pos
Definition: block.h:579
const lzma_allocator const uint8_t size_t in_size
Definition: block.h:527
const lzma_allocator * allocator
Definition: block.h:377
const lzma_allocator const uint8_t * in
Definition: block.h:527
const lzma_allocator const uint8_t size_t uint8_t * out
Definition: block.h:528
const lzma_filter * filters
Definition: container.h:315
uint64_t memlimit
Definition: container.h:537
#define NULL
Definition: cris-opc.c:27
static lzma_stream strm
Definition: full_flush.c:20
#define restrict
void lzma_lz_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size)
Definition: lz_decoder.c:307
LZ out window.
bool lzma_lzma_lclppb_decode(lzma_options_lzma *options, uint8_t byte)
Decodes the LZMA Properties byte (lc/lp/pb)
uint64_t lzma_lzma_decoder_memusage(const void *options)
lzma_ret lzma_lzma_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Allocates and initializes LZMA decoder.
Definition: lzma_decoder.c:987
LZMA decoder API.
int size_t
Definition: sftypes.h:40
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
#define d(i)
Definition: sha256.c:44
#define UINT32_MAX
Custom functions for memory handling.
Definition: base.h:372
size_t pos
Position in the header fields.
Definition: alone_decoder.c:35
enum lzma_alone_coder::@640 sequence
uint64_t memusage
Amount of memory actually needed (only an estimate)
Definition: alone_decoder.c:44
lzma_next_coder next
Definition: alone_decoder.c:19
uint64_t memlimit
Memory usage limit.
Definition: alone_decoder.c:41
lzma_vli uncompressed_size
Uncompressed size decoded from the header.
Definition: alone_decoder.c:38
lzma_options_lzma options
Definition: alone_decoder.c:48
bool supported_actions[LZMA_ACTION_MAX+1]
Indicates which lzma_action values are allowed by next.code.
Definition: common.h:220
Hold data and function pointers of the next filter in the chain.
Definition: common.h:135
lzma_code_function code
Pointer to function to do the actual coding.
Definition: common.h:150
void * coder
Pointer to coder-specific data.
Definition: common.h:137
lzma_end_function end
Definition: common.h:155
lzma_ret(* memconfig)(void *coder, uint64_t *memusage, uint64_t *old_memlimit, uint64_t new_memlimit)
Definition: common.h:168
Options specific to the LZMA1 and LZMA2 filters.
Definition: lzma12.h:185
const uint8_t * preset_dict
Pointer to an initial dictionary.
Definition: lzma12.h:240
uint32_t preset_dict_size
Size of the preset dictionary.
Definition: lzma12.h:254
uint32_t dict_size
Dictionary size in bytes.
Definition: lzma12.h:217
Passing data to and from liblzma.
Definition: base.h:485
lzma_internal * internal
Definition: base.h:505
#define LZMA_NEXT_CODER_INIT
Macro to initialize lzma_next_coder structure.
Definition: common.h:180
#define LZMA_MEMUSAGE_BASE
Definition: common.h:63
#define lzma_next_coder_init(func, next, allocator)
Definition: common.h:291
#define lzma_next_strm_init(func, strm,...)
Definition: common.h:303
void * lzma_alloc(size_t size, const lzma_allocator *allocator) lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
Allocates memory.
#define my_max(x, y)
Definition: sysdefs.h:186
uint64_t lzma_vli
Variable-length integer type.
Definition: vli.h:63
#define LZMA_VLI_C(n)
VLI constant suffix.
Definition: vli.h:49
#define LZMA_VLI_UNKNOWN
VLI value to denote that the value is unknown.
Definition: vli.h:39
lzma_ret
Return values used by several functions in liblzma.
Definition: base.h:57
@ LZMA_PROG_ERROR
Programming error.
Definition: base.h:218
@ LZMA_MEM_ERROR
Cannot allocate memory.
Definition: base.h:128
@ LZMA_FORMAT_ERROR
Memory usage limit was reached.
Definition: base.h:150
@ LZMA_MEMLIMIT_ERROR
Definition: base.h:140
@ LZMA_OK
Operation completed successfully.
Definition: base.h:58
lzma_action
The ‘action’ argument for lzma_code()
Definition: base.h:250
@ LZMA_FINISH
Finish the coding operation.
Definition: base.h:328
@ LZMA_RUN
Continue coding.
Definition: base.h:251
lzma_ret lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Definition: common.c:116
void lzma_free(void *ptr, const lzma_allocator *allocator)
Frees memory.
Definition: common.c:78
void lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
Definition: common.c:145