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

Common functions needed in many places in liblzma. More...

#include "common.h"

Go to the source code of this file.

Functions

 LZMA_API (uint32_t)
 
 LZMA_API (const char *)
 Run-time version as a string. More...
 
void * lzma_attribute ((__malloc__))
 
void lzma_free (void *ptr, const lzma_allocator *allocator)
 Frees memory. More...
 
size_t lzma_bufcpy (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_ret lzma_next_filter_init (lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter_info *filters)
 
lzma_ret lzma_next_filter_update (lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter *reversed_filters)
 
void lzma_next_end (lzma_next_coder *next, const lzma_allocator *allocator)
 
lzma_ret lzma_strm_init (lzma_stream *strm)
 
 LZMA_API (lzma_ret)
 
 LZMA_API (void)
 
 LZMA_API (lzma_check)
 
 LZMA_API (uint64_t)
 Calculate approximate memory usage of easy encoder. More...
 

Detailed Description

Common functions needed in many places in liblzma.

Definition in file common.c.

Function Documentation

◆ LZMA_API() [1/6]

LZMA_API ( const char *  ) const

Run-time version as a string.

This function may be useful if you want to display which version of liblzma your application is currently using.

Definition at line 27 of file common.c.

29 {
30  return LZMA_VERSION_STRING;
31 }
#define LZMA_VERSION_STRING
Compile-time version as a string.
Definition: version.h:92

References LZMA_VERSION_STRING.

◆ LZMA_API() [2/6]

LZMA_API ( lzma_check  )

Definition at line 385 of file common.c.

387 {
388  // Return LZMA_CHECK_NONE if we cannot know the check type.
389  // It's a bug in the application if this happens.
390  if (strm->internal->next.get_check == NULL)
391  return LZMA_CHECK_NONE;
392 
394 }
@ LZMA_CHECK_NONE
Definition: check.h:28
#define NULL
Definition: cris-opc.c:27
static lzma_stream strm
Definition: full_flush.c:20
lzma_next_coder next
The actual coder that should do something useful.
Definition: common.h:198
void * coder
Pointer to coder-specific data.
Definition: common.h:137
lzma_check(* get_check)(const void *coder)
Definition: common.h:164
lzma_internal * internal
Definition: base.h:505

References lzma_next_coder_s::coder, lzma_next_coder_s::get_check, lzma_stream::internal, LZMA_CHECK_NONE, lzma_internal_s::next, NULL, and strm.

◆ LZMA_API() [3/6]

LZMA_API ( lzma_ret  )

Definition at line 196 of file common.c.

198 {
199  // Sanity checks
200  if ((strm->next_in == NULL && strm->avail_in != 0)
201  || (strm->next_out == NULL && strm->avail_out != 0)
202  || strm->internal == NULL
203  || strm->internal->next.code == NULL
204  || (unsigned int)(action) > LZMA_ACTION_MAX
206  return LZMA_PROG_ERROR;
207 
208  // Check if unsupported members have been set to non-zero or non-NULL,
209  // which would indicate that some new feature is wanted.
210  if (strm->reserved_ptr1 != NULL
211  || strm->reserved_ptr2 != NULL
212  || strm->reserved_ptr3 != NULL
213  || strm->reserved_ptr4 != NULL
214  || strm->reserved_int1 != 0
215  || strm->reserved_int2 != 0
216  || strm->reserved_int3 != 0
217  || strm->reserved_int4 != 0
220  return LZMA_OPTIONS_ERROR;
221 
222  switch (strm->internal->sequence) {
223  case ISEQ_RUN:
224  switch (action) {
225  case LZMA_RUN:
226  break;
227 
228  case LZMA_SYNC_FLUSH:
229  strm->internal->sequence = ISEQ_SYNC_FLUSH;
230  break;
231 
232  case LZMA_FULL_FLUSH:
233  strm->internal->sequence = ISEQ_FULL_FLUSH;
234  break;
235 
236  case LZMA_FINISH:
237  strm->internal->sequence = ISEQ_FINISH;
238  break;
239 
240  case LZMA_FULL_BARRIER:
241  strm->internal->sequence = ISEQ_FULL_BARRIER;
242  break;
243  }
244 
245  break;
246 
247  case ISEQ_SYNC_FLUSH:
248  // The same action must be used until we return
249  // LZMA_STREAM_END, and the amount of input must not change.
250  if (action != LZMA_SYNC_FLUSH
252  return LZMA_PROG_ERROR;
253 
254  break;
255 
256  case ISEQ_FULL_FLUSH:
257  if (action != LZMA_FULL_FLUSH
259  return LZMA_PROG_ERROR;
260 
261  break;
262 
263  case ISEQ_FINISH:
264  if (action != LZMA_FINISH
266  return LZMA_PROG_ERROR;
267 
268  break;
269 
270  case ISEQ_FULL_BARRIER:
273  return LZMA_PROG_ERROR;
274 
275  break;
276 
277  case ISEQ_END:
278  return LZMA_STREAM_END;
279 
280  case ISEQ_ERROR:
281  default:
282  return LZMA_PROG_ERROR;
283  }
284 
285  size_t in_pos = 0;
286  size_t out_pos = 0;
287  lzma_ret ret = strm->internal->next.code(
291 
292  strm->next_in += in_pos;
293  strm->avail_in -= in_pos;
294  strm->total_in += in_pos;
295 
296  strm->next_out += out_pos;
297  strm->avail_out -= out_pos;
298  strm->total_out += out_pos;
299 
301 
302  // Cast is needed to silence a warning about LZMA_TIMED_OUT, which
303  // isn't part of lzma_ret enumeration.
304  switch ((unsigned int)(ret)) {
305  case LZMA_OK:
306  // Don't return LZMA_BUF_ERROR when it happens the first time.
307  // This is to avoid returning LZMA_BUF_ERROR when avail_out
308  // was zero but still there was no more data left to written
309  // to next_out.
310  if (out_pos == 0 && in_pos == 0) {
312  ret = LZMA_BUF_ERROR;
313  else
314  strm->internal->allow_buf_error = true;
315  } else {
316  strm->internal->allow_buf_error = false;
317  }
318  break;
319 
320  case LZMA_TIMED_OUT:
321  strm->internal->allow_buf_error = false;
322  ret = LZMA_OK;
323  break;
324 
325  case LZMA_STREAM_END:
326  if (strm->internal->sequence == ISEQ_SYNC_FLUSH
327  || strm->internal->sequence == ISEQ_FULL_FLUSH
328  || strm->internal->sequence
329  == ISEQ_FULL_BARRIER)
330  strm->internal->sequence = ISEQ_RUN;
331  else
332  strm->internal->sequence = ISEQ_END;
333 
334  // Fall through
335 
336  case LZMA_NO_CHECK:
338  case LZMA_GET_CHECK:
339  case LZMA_MEMLIMIT_ERROR:
340  // Something else than LZMA_OK, but not a fatal error,
341  // that is, coding may be continued (except if ISEQ_END).
342  strm->internal->allow_buf_error = false;
343  break;
344 
345  default:
346  // All the other errors are fatal; coding cannot be continued.
347  assert(ret != LZMA_BUF_ERROR);
348  strm->internal->sequence = ISEQ_ERROR;
349  break;
350  }
351 
352  return ret;
353 }
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
assert(limit<=UINT32_MAX/2)
bool supported_actions[LZMA_ACTION_MAX+1]
Indicates which lzma_action values are allowed by next.code.
Definition: common.h:220
bool allow_buf_error
Definition: common.h:224
enum lzma_internal_s::@645 sequence
size_t avail_in
Definition: common.h:217
lzma_code_function code
Pointer to function to do the actual coding.
Definition: common.h:150
uint64_t reserved_int1
Definition: base.h:517
void * reserved_ptr3
Definition: base.h:515
uint8_t * next_out
Definition: base.h:490
uint64_t total_in
Definition: base.h:488
size_t reserved_int3
Definition: base.h:519
const lzma_allocator * allocator
Custom memory allocation functions.
Definition: base.h:502
size_t avail_out
Definition: base.h:491
const uint8_t * next_in
Definition: base.h:486
uint64_t total_out
Definition: base.h:492
void * reserved_ptr1
Definition: base.h:513
lzma_reserved_enum reserved_enum2
Definition: base.h:522
lzma_reserved_enum reserved_enum1
Definition: base.h:521
void * reserved_ptr2
Definition: base.h:514
size_t avail_in
Definition: base.h:487
void * reserved_ptr4
Definition: base.h:516
size_t reserved_int4
Definition: base.h:520
uint64_t reserved_int2
Definition: base.h:518
#define LZMA_TIMED_OUT
Definition: common.h:88
#define LZMA_ACTION_MAX
Largest valid lzma_action value as unsigned integer.
Definition: common.h:81
@ LZMA_RESERVED_ENUM
Definition: base.h:45
lzma_ret
Return values used by several functions in liblzma.
Definition: base.h:57
@ LZMA_PROG_ERROR
Programming error.
Definition: base.h:218
@ LZMA_STREAM_END
End of stream was reached.
Definition: base.h:63
@ LZMA_UNSUPPORTED_CHECK
Cannot calculate the integrity check.
Definition: base.h:90
@ LZMA_BUF_ERROR
No progress is possible.
Definition: base.h:191
@ LZMA_MEMLIMIT_ERROR
Definition: base.h:140
@ LZMA_GET_CHECK
Integrity check type is now available.
Definition: base.h:115
@ LZMA_NO_CHECK
Input stream has no integrity check.
Definition: base.h:75
@ LZMA_OPTIONS_ERROR
Invalid or unsupported options.
Definition: base.h:160
@ LZMA_OK
Operation completed successfully.
Definition: base.h:58
@ LZMA_SYNC_FLUSH
Make all the input available at output.
Definition: base.h:265
@ LZMA_FINISH
Finish the coding operation.
Definition: base.h:328
@ LZMA_RUN
Continue coding.
Definition: base.h:251
@ LZMA_FULL_FLUSH
Finish encoding of the current Block.
Definition: base.h:290
@ LZMA_FULL_BARRIER
Finish encoding of the current Block.
Definition: base.h:305

References test-lz4-speed::action, lzma_stream::allocator, lzma_internal_s::allow_buf_error, assert(), lzma_stream::avail_in, lzma_internal_s::avail_in, lzma_stream::avail_out, lzma_next_coder_s::code, lzma_next_coder_s::coder, in_pos, lzma_stream::internal, LZMA_ACTION_MAX, LZMA_BUF_ERROR, LZMA_FINISH, LZMA_FULL_BARRIER, LZMA_FULL_FLUSH, LZMA_GET_CHECK, LZMA_MEMLIMIT_ERROR, LZMA_NO_CHECK, LZMA_OK, LZMA_OPTIONS_ERROR, LZMA_PROG_ERROR, LZMA_RESERVED_ENUM, LZMA_RUN, LZMA_STREAM_END, LZMA_SYNC_FLUSH, LZMA_TIMED_OUT, LZMA_UNSUPPORTED_CHECK, lzma_internal_s::next, lzma_stream::next_in, lzma_stream::next_out, NULL, out_pos, lzma_stream::reserved_enum1, lzma_stream::reserved_enum2, lzma_stream::reserved_int1, lzma_stream::reserved_int2, lzma_stream::reserved_int3, lzma_stream::reserved_int4, lzma_stream::reserved_ptr1, lzma_stream::reserved_ptr2, lzma_stream::reserved_ptr3, lzma_stream::reserved_ptr4, lzma_internal_s::sequence, strm, lzma_internal_s::supported_actions, lzma_stream::total_in, and lzma_stream::total_out.

◆ LZMA_API() [4/6]

LZMA_API ( uint32_t  )

Definition at line 20 of file common.c.

22 {
23  return LZMA_VERSION;
24 }
#define LZMA_VERSION
Compile-time version number.
Definition: version.h:57

References LZMA_VERSION.

◆ LZMA_API() [5/6]

LZMA_API ( uint64_t  )

Calculate approximate memory usage of easy encoder.

Get the total amount of physical memory (RAM) in bytes.

Calculate approximate memory usage of multithreaded .xz encoder.

Calculate approximate decoder memory usage of a preset.

This function is a wrapper for lzma_raw_encoder_memusage().

Parameters
presetCompression preset (level and possible flags)
Returns
Number of bytes of memory required for the given preset when encoding. If an error occurs, for example due to unsupported preset, UINT64_MAX is returned.

This function is a wrapper for lzma_raw_decoder_memusage().

Parameters
presetCompression preset (level and possible flags)
Returns
Number of bytes of memory required to decompress a file that was compressed using the given preset. If an error occurs, for example due to unsupported preset, UINT64_MAX is returned.

Since doing the encoding in threaded mode doesn't affect the memory requirements of single-threaded decompressor, you can use lzma_easy_decoder_memusage(options->preset) or lzma_raw_decoder_memusage(options->filters) to calculate the decompressor memory requirements.

Parameters
optionsCompression options
Returns
Number of bytes of memory required for encoding with the given options. If an error occurs, for example due to unsupported preset or filter chain, UINT64_MAX is returned.

Calculate approximate memory usage of easy encoder.

Get the uncompressed size of the file.

Get the total size of the file.

Get the total size of the Blocks.

Get the total size of the Stream.

Get the size of the Index field as bytes.

Get the number of Blocks.

Get the number of Streams.

Calculate the memory usage of an existing lzma_index.

On disk, the size of the Index field depends on both the number of Records stored and how big values the Records store (due to variable-length integer encoding). When the Index is kept in lzma_index structure, the memory usage depends only on the number of Records/Blocks stored in the Index(es), and in case of concatenated lzma_indexes, the number of Streams. The size in RAM is almost always significantly bigger than in the encoded form on disk.

This function calculates an approximate amount of memory needed hold the given number of Streams and Blocks in lzma_index structure. This value may vary between CPU architectures and also between liblzma versions if the internal implementation is modified.

This is a shorthand for lzma_index_memusage(lzma_index_stream_count(i), lzma_index_block_count(i)).

This returns the total number of Blocks in lzma_index. To get number of Blocks in individual Streams, use lzma_index_iter.

This is needed to verify the Backward Size field in the Stream Footer.

If multiple lzma_indexes have been combined, this works as if the Blocks were in a single Stream. This is useful if you are going to combine Blocks from multiple Streams into a single new Stream.

This doesn't include the Stream Header, Stream Footer, Stream Padding, or Index fields.

When no lzma_indexes have been combined with lzma_index_cat() and there is no Stream Padding, this function is identical to lzma_index_stream_size(). If multiple lzma_indexes have been combined, this includes also the headers of each separate Stream and the possible Stream Padding fields.

Definition at line 397 of file common.c.

399 {
400  uint64_t memusage;
401  uint64_t old_memlimit;
402 
403  if (strm == NULL || strm->internal == NULL
407  &memusage, &old_memlimit, 0) != LZMA_OK)
408  return 0;
409 
410  return memusage;
411 }
unsigned long uint64_t
Definition: sftypes.h:28
lzma_ret(* memconfig)(void *coder, uint64_t *memusage, uint64_t *old_memlimit, uint64_t new_memlimit)
Definition: common.h:168

References lzma_next_coder_s::coder, lzma_stream::internal, LZMA_OK, lzma_next_coder_s::memconfig, lzma_internal_s::next, NULL, and strm.

◆ LZMA_API() [6/6]

LZMA_API ( void  )

Definition at line 356 of file common.c.

358 {
359  if (strm != NULL && strm->internal != NULL) {
362  strm->internal = NULL;
363  }
364 
365  return;
366 }
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 lzma_stream::allocator, lzma_stream::internal, lzma_free(), lzma_next_end(), lzma_internal_s::next, NULL, and strm.

◆ lzma_attribute()

void * lzma_attribute ( (__malloc__)  )

Definition at line 38 of file common.c.

40 {
41  // Some malloc() variants return NULL if called with size == 0.
42  if (size == 0)
43  size = 1;
44 
45  void *ptr;
46 
47  if (allocator != NULL && allocator->alloc != NULL)
48  ptr = allocator->alloc(allocator->opaque, 1, size);
49  else
50  ptr = malloc(size);
51 
52  return ptr;
53 }
const lzma_allocator * allocator
Definition: block.h:377
voidpf void uLong size
Definition: ioapi.h:138
void * malloc(size_t size)
Definition: malloc.c:123
void * opaque
Pointer passed to .alloc() and .free()
Definition: base.h:432
void *LZMA_API_CALL * alloc(void *opaque, size_t nmemb, size_t size)
Pointer to a custom memory allocation function.

References lzma_allocator::alloc(), allocator, malloc(), NULL, and lzma_allocator::opaque.

◆ lzma_bufcpy()

size_t lzma_bufcpy ( 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 
)

Copy as much data as possible from in[] to out[] and update *in_pos and *out_pos accordingly. Returns the number of bytes copied.

Definition at line 94 of file common.c.

97 {
98  const size_t in_avail = in_size - *in_pos;
99  const size_t out_avail = out_size - *out_pos;
100  const size_t copy_size = my_min(in_avail, out_avail);
101 
102  // Call memcpy() only if there is something to copy. If there is
103  // nothing to copy, in or out might be NULL and then the memcpy()
104  // call would trigger undefined behavior.
105  if (copy_size > 0)
106  memcpy(out + *out_pos, in + *in_pos, copy_size);
107 
108  *in_pos += copy_size;
109  *out_pos += copy_size;
110 
111  return copy_size;
112 }
const lzma_allocator const uint8_t size_t in_size
Definition: block.h:527
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
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define my_min(x, y)
Definition: sysdefs.h:185

References in, in_pos, in_size, memcpy(), my_min, out, and out_pos.

Referenced by alone_encode(), block_decode(), block_encode(), copy_or_code(), dict_write(), fill_window(), lzma2_encode(), lzma_outq_read(), simple_code(), stream_decode(), stream_encode(), stream_encode_in(), and stream_encode_mt().

◆ lzma_free()

◆ lzma_next_end()

void lzma_next_end ( lzma_next_coder next,
const lzma_allocator allocator 
)

Frees the memory allocated for next->coder either using next->end or, if next->end is NULL, using lzma_free.

Definition at line 145 of file common.c.

146 {
147  if (next->init != (uintptr_t)(NULL)) {
148  // To avoid tiny end functions that simply call
149  // lzma_free(coder, allocator), we allow leaving next->end
150  // NULL and call lzma_free() here.
151  if (next->end != NULL)
152  next->end(next->coder, allocator);
153  else
154  lzma_free(next->coder, allocator);
155 
156  // Reset the variables so the we don't accidentally think
157  // that it is an already initialized coder.
158  *next = LZMA_NEXT_CODER_INIT;
159  }
160 
161  return;
162 }
_W64 unsigned int uintptr_t
uintptr_t init
Definition: common.h:147
lzma_end_function end
Definition: common.h:155
#define LZMA_NEXT_CODER_INIT
Macro to initialize lzma_next_coder structure.
Definition: common.h:180

References allocator, lzma_next_coder_s::coder, lzma_next_coder_s::end, lzma_next_coder_s::init, lzma_free(), LZMA_NEXT_CODER_INIT, and NULL.

Referenced by alone_decoder_end(), alone_encoder_end(), auto_decoder_end(), block_decoder_end(), block_encode_normal(), block_encoder_end(), delta_coder_end(), lz_decoder_end(), lz_encoder_end(), LZMA_API(), lzma_raw_coder_init(), simple_coder_end(), stream_decoder_end(), stream_encoder_end(), stream_encoder_mt_end(), and worker_start().

◆ lzma_next_filter_init()

lzma_ret lzma_next_filter_init ( lzma_next_coder next,
const lzma_allocator allocator,
const lzma_filter_info filters 
)

Initializes the next filter in the chain, if any. This takes care of freeing the memory of previously initialized filter if it is different than the filter being initialized now. This way the actual filter initialization functions don't need to use lzma_next_coder_init macro.

Definition at line 116 of file common.c.

118 {
120  next->id = filters[0].id;
121  return filters[0].init == NULL
122  ? LZMA_OK : filters[0].init(next, allocator, filters);
123 }
const lzma_filter * filters
Definition: container.h:315
lzma_vli id
Filter ID.
Definition: filter.h:54
lzma_vli id
Definition: common.h:141
bool init
Definition: core.c:77
#define lzma_next_coder_init(func, next, allocator)
Definition: common.h:291

References allocator, filters, lzma_filter::id, lzma_next_coder_s::id, init, lzma_next_coder_init, LZMA_OK, and NULL.

Referenced by alone_decode(), alone_encoder_init(), lzma_delta_coder_init(), lzma_lz_decoder_init(), lzma_lz_encoder_init(), lzma_raw_coder_init(), and lzma_simple_coder_init().

◆ lzma_next_filter_update()

lzma_ret lzma_next_filter_update ( lzma_next_coder next,
const lzma_allocator allocator,
const lzma_filter reversed_filters 
)

Update the next filter in the chain, if any. This checks that the application is not trying to change the Filter IDs.

Definition at line 127 of file common.c.

129 {
130  // Check that the application isn't trying to change the Filter ID.
131  // End of filters is indicated with LZMA_VLI_UNKNOWN in both
132  // reversed_filters[0].id and next->id.
133  if (reversed_filters[0].id != next->id)
134  return LZMA_PROG_ERROR;
135 
136  if (reversed_filters[0].id == LZMA_VLI_UNKNOWN)
137  return LZMA_OK;
138 
139  assert(next->update != NULL);
140  return next->update(next->coder, allocator, NULL, reversed_filters);
141 }
lzma_ret(* update)(void *coder, const lzma_allocator *allocator, const lzma_filter *filters, const lzma_filter *reversed_filters)
Definition: common.h:173
#define LZMA_VLI_UNKNOWN
VLI value to denote that the value is unknown.
Definition: vli.h:39

References allocator, assert(), lzma_next_coder_s::coder, lzma_next_coder_s::id, LZMA_OK, LZMA_PROG_ERROR, LZMA_VLI_UNKNOWN, NULL, and lzma_next_coder_s::update.

Referenced by block_encoder_update(), delta_encoder_update(), lz_encoder_update(), and simple_coder_update().

◆ lzma_strm_init()

lzma_ret lzma_strm_init ( lzma_stream strm)

Allocates strm->internal if it is NULL, and initializes *strm and strm->internal. This function is only called via lzma_next_strm_init macro.

Definition at line 170 of file common.c.

171 {
172  if (strm == NULL)
173  return LZMA_PROG_ERROR;
174 
175  if (strm->internal == NULL) {
177  strm->allocator);
178  if (strm->internal == NULL)
179  return LZMA_MEM_ERROR;
180 
182  }
183 
185  sizeof(strm->internal->supported_actions));
186  strm->internal->sequence = ISEQ_RUN;
187  strm->internal->allow_buf_error = false;
188 
189  strm->total_in = 0;
190  strm->total_out = 0;
191 
192  return LZMA_OK;
193 }
void * lzma_alloc(size_t size, const lzma_allocator *allocator) lzma_attribute((__malloc__)) lzma_attr_alloc_size(1)
Allocates memory.
#define memzero(s, n)
Definition: sysdefs.h:180
@ LZMA_MEM_ERROR
Cannot allocate memory.
Definition: base.h:128

References lzma_stream::allocator, lzma_internal_s::allow_buf_error, lzma_stream::internal, lzma_alloc(), LZMA_MEM_ERROR, LZMA_NEXT_CODER_INIT, LZMA_OK, LZMA_PROG_ERROR, memzero, lzma_internal_s::next, NULL, lzma_internal_s::sequence, strm, lzma_internal_s::supported_actions, lzma_stream::total_in, and lzma_stream::total_out.