Rizin
unix-like reverse engineering framework and cli tools
stream_buffer_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 "stream_decoder.h"
14 
15 
17 lzma_stream_buffer_decode(uint64_t *memlimit, uint32_t flags,
19  const uint8_t *in, size_t *in_pos, size_t in_size,
20  uint8_t *out, size_t *out_pos, size_t out_size)
21 {
22  // Sanity checks
23  if (in_pos == NULL || (in == NULL && *in_pos != in_size)
24  || *in_pos > in_size || out_pos == NULL
25  || (out == NULL && *out_pos != out_size)
26  || *out_pos > out_size)
27  return LZMA_PROG_ERROR;
28 
29  // Catch flags that are not allowed in buffer-to-buffer decoding.
31  return LZMA_PROG_ERROR;
32 
33  // Initialize the Stream decoder.
34  // TODO: We need something to tell the decoder that it can use the
35  // output buffer as workspace, and thus save significant amount of RAM.
36  lzma_next_coder stream_decoder = LZMA_NEXT_CODER_INIT;
38  &stream_decoder, allocator, *memlimit, flags);
39 
40  if (ret == LZMA_OK) {
41  // Save the positions so that we can restore them in case
42  // an error occurs.
43  const size_t in_start = *in_pos;
44  const size_t out_start = *out_pos;
45 
46  // Do the actual decoding.
47  ret = stream_decoder.code(stream_decoder.coder, allocator,
48  in, in_pos, in_size, out, out_pos, out_size,
49  LZMA_FINISH);
50 
51  if (ret == LZMA_STREAM_END) {
52  ret = LZMA_OK;
53  } else {
54  // Something went wrong, restore the positions.
55  *in_pos = in_start;
56  *out_pos = out_start;
57 
58  if (ret == LZMA_OK) {
59  // Either the input was truncated or the
60  // output buffer was too small.
62  || *out_pos == out_size);
63 
64  // If all the input was consumed, then the
65  // input is truncated, even if the output
66  // buffer is also full. This is because
67  // processing the last byte of the Stream
68  // never produces output.
69  if (*in_pos == in_size)
70  ret = LZMA_DATA_ERROR;
71  else
72  ret = LZMA_BUF_ERROR;
73 
74  } else if (ret == LZMA_MEMLIMIT_ERROR) {
75  // Let the caller know how much memory would
76  // have been needed.
77  uint64_t memusage;
78  (void)stream_decoder.memconfig(
79  stream_decoder.coder,
80  memlimit, &memusage, 0);
81  }
82  }
83  }
84 
85  // Free the decoder memory. This needs to be done even if
86  // initialization fails, because the internal API doesn't
87  // require the initialization function to free its memory on error.
88  lzma_next_end(&stream_decoder, allocator);
89 
90  return ret;
91 }
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
#define LZMA_TELL_ANY_CHECK
Definition: container.h:474
uint64_t memlimit
Definition: container.h:537
#define NULL
Definition: cris-opc.c:27
assert(limit<=UINT32_MAX/2)
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123
unsigned int uint32_t
Definition: sftypes.h:29
unsigned long uint64_t
Definition: sftypes.h:28
unsigned char uint8_t
Definition: sftypes.h:31
LZMA_API(lzma_ret)
lzma_ret lzma_stream_decoder_init(lzma_next_coder *next, const lzma_allocator *allocator, uint64_t memlimit, uint32_t flags)
Decodes .xz Streams.
Custom functions for memory handling.
Definition: base.h:372
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_ret(* memconfig)(void *coder, uint64_t *memusage, uint64_t *old_memlimit, uint64_t new_memlimit)
Definition: common.h:168
#define LZMA_NEXT_CODER_INIT
Macro to initialize lzma_next_coder structure.
Definition: common.h:180
lzma_ret
Return values used by several functions in liblzma.
Definition: base.h:57
@ LZMA_PROG_ERROR
Programming error.
Definition: base.h:218
@ LZMA_DATA_ERROR
Data is corrupt.
Definition: base.h:172
@ LZMA_STREAM_END
End of stream was reached.
Definition: base.h:63
@ LZMA_BUF_ERROR
No progress is possible.
Definition: base.h:191
@ LZMA_MEMLIMIT_ERROR
Definition: base.h:140
@ LZMA_OK
Operation completed successfully.
Definition: base.h:58
@ LZMA_FINISH
Finish the coding operation.
Definition: base.h:328
void lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
Definition: common.c:145