Rizin
unix-like reverse engineering framework and cli tools
alone_decoder.c File Reference

Decoder for LZMA_Alone files. More...

#include "alone_decoder.h"
#include "lzma_decoder.h"
#include "lz_decoder.h"

Go to the source code of this file.

Classes

struct  lzma_alone_coder
 

Functions

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)
 
static void alone_decoder_end (void *coder_ptr, const lzma_allocator *allocator)
 
static lzma_ret alone_decoder_memconfig (void *coder_ptr, uint64_t *memusage, uint64_t *old_memlimit, uint64_t new_memlimit)
 
lzma_ret lzma_alone_decoder_init (lzma_next_coder *next, const lzma_allocator *allocator, uint64_t memlimit, bool picky)
 
 LZMA_API (lzma_ret)
 

Detailed Description

Decoder for LZMA_Alone files.

Definition in file alone_decoder.c.

Function Documentation

◆ alone_decode()

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 
)
static

Definition at line 53 of file alone_decoder.c.

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 }
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
#define NULL
Definition: cris-opc.c:27
void lzma_lz_decoder_uncompressed(void *coder_ptr, lzma_vli uncompressed_size)
Definition: lz_decoder.c:307
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
int size_t
Definition: sftypes.h:40
unsigned int uint32_t
Definition: sftypes.h:29
#define d(i)
Definition: sha256.c:44
#define UINT32_MAX
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
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
uint32_t dict_size
Dictionary size in bytes.
Definition: lzma12.h:217
#define LZMA_MEMUSAGE_BASE
Definition: common.h:63
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_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_ret lzma_next_filter_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
Definition: common.c:116

References test-lz4-speed::action, allocator, lzma_next_coder_s::code, lzma_next_coder_s::coder, d, lzma_options_lzma::dict_size, filters, in, in_pos, in_size, LZMA_FORMAT_ERROR, lzma_lz_decoder_uncompressed(), lzma_lzma_decoder_init(), lzma_lzma_decoder_memusage(), lzma_lzma_lclppb_decode(), LZMA_MEMLIMIT_ERROR, LZMA_MEMUSAGE_BASE, lzma_next_filter_init(), LZMA_OK, LZMA_PROG_ERROR, LZMA_VLI_C, LZMA_VLI_UNKNOWN, lzma_alone_coder::memlimit, lzma_alone_coder::memusage, lzma_alone_coder::next, NULL, lzma_alone_coder::options, out, out_pos, lzma_alone_coder::picky, lzma_alone_coder::pos, lzma_alone_coder::sequence, UINT32_MAX, and lzma_alone_coder::uncompressed_size.

Referenced by lzma_alone_decoder_init().

◆ alone_decoder_end()

static void alone_decoder_end ( void *  coder_ptr,
const lzma_allocator allocator 
)
static

Definition at line 170 of file alone_decoder.c.

171 {
172  lzma_alone_coder *coder = coder_ptr;
173  lzma_next_end(&coder->next, allocator);
174  lzma_free(coder, allocator);
175  return;
176 }
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

References allocator, lzma_free(), lzma_next_end(), and lzma_alone_coder::next.

Referenced by lzma_alone_decoder_init().

◆ alone_decoder_memconfig()

static lzma_ret alone_decoder_memconfig ( void *  coder_ptr,
uint64_t memusage,
uint64_t old_memlimit,
uint64_t  new_memlimit 
)
static

Definition at line 180 of file alone_decoder.c.

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 }

References LZMA_MEMLIMIT_ERROR, LZMA_OK, lzma_alone_coder::memlimit, and lzma_alone_coder::memusage.

Referenced by lzma_alone_decoder_init().

◆ lzma_alone_decoder_init()

lzma_ret lzma_alone_decoder_init ( lzma_next_coder next,
const lzma_allocator allocator,
uint64_t  memlimit,
bool  picky 
)

Definition at line 200 of file alone_decoder.c.

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 }
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)
uint64_t memlimit
Definition: container.h:537
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
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
#define LZMA_NEXT_CODER_INIT
Macro to initialize lzma_next_coder structure.
Definition: common.h:180
#define lzma_next_coder_init(func, next, allocator)
Definition: common.h:291
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
@ LZMA_MEM_ERROR
Cannot allocate memory.
Definition: base.h:128

References allocator, alone_decode(), alone_decoder_end(), alone_decoder_memconfig(), lzma_next_coder_s::code, lzma_next_coder_s::coder, lzma_options_lzma::dict_size, lzma_next_coder_s::end, lzma_alloc(), LZMA_MEM_ERROR, LZMA_MEMUSAGE_BASE, LZMA_NEXT_CODER_INIT, lzma_next_coder_init, LZMA_OK, lzma_next_coder_s::memconfig, memlimit, lzma_alone_coder::memlimit, lzma_alone_coder::memusage, my_max, lzma_alone_coder::next, NULL, lzma_alone_coder::options, lzma_alone_coder::picky, lzma_alone_coder::pos, lzma_options_lzma::preset_dict, lzma_options_lzma::preset_dict_size, lzma_alone_coder::sequence, and lzma_alone_coder::uncompressed_size.

Referenced by auto_decode(), and LZMA_API().

◆ LZMA_API()

LZMA_API ( lzma_ret  )

Definition at line 233 of file alone_decoder.c.

235 {
237 
240 
241  return LZMA_OK;
242 }
static lzma_stream strm
Definition: full_flush.c:20
bool supported_actions[LZMA_ACTION_MAX+1]
Indicates which lzma_action values are allowed by next.code.
Definition: common.h:220
lzma_internal * internal
Definition: base.h:505
#define lzma_next_strm_init(func, strm,...)
Definition: common.h:303
@ LZMA_FINISH
Finish the coding operation.
Definition: base.h:328
@ LZMA_RUN
Continue coding.
Definition: base.h:251

References lzma_stream::internal, lzma_alone_decoder_init(), LZMA_FINISH, lzma_next_strm_init, LZMA_OK, LZMA_RUN, memlimit, strm, and lzma_internal_s::supported_actions.