Rizin
unix-like reverse engineering framework and cli tools
block_encoder.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 "block_encoder.h"
14 #include "filter_encoder.h"
15 #include "check.h"
16 
17 
18 typedef struct {
20  lzma_next_coder next;
21 
25  lzma_block *block;
26 
27  enum {
28  SEQ_CODE,
29  SEQ_PADDING,
30  SEQ_CHECK,
31  } sequence;
32 
35 
38 
40  size_t pos;
41 
45 
46 
47 static lzma_ret
48 block_encode(void *coder_ptr, const lzma_allocator *allocator,
49  const uint8_t *restrict in, size_t *restrict in_pos,
50  size_t in_size, uint8_t *restrict out,
51  size_t *restrict out_pos, size_t out_size, lzma_action action)
52 {
53  lzma_block_coder *coder = coder_ptr;
54 
55  // Check that our amount of input stays in proper limits.
56  if (LZMA_VLI_MAX - coder->uncompressed_size < in_size - *in_pos)
57  return LZMA_DATA_ERROR;
58 
59  switch (coder->sequence) {
60  case SEQ_CODE: {
61  const size_t in_start = *in_pos;
62  const size_t out_start = *out_pos;
63 
64  const lzma_ret ret = coder->next.code(coder->next.coder,
66  out, out_pos, out_size, action);
67 
68  const size_t in_used = *in_pos - in_start;
69  const size_t out_used = *out_pos - out_start;
70 
71  if (COMPRESSED_SIZE_MAX - coder->compressed_size < out_used)
72  return LZMA_DATA_ERROR;
73 
74  coder->compressed_size += out_used;
75 
76  // No need to check for overflow because we have already
77  // checked it at the beginning of this function.
78  coder->uncompressed_size += in_used;
79 
80  lzma_check_update(&coder->check, coder->block->check,
81  in + in_start, in_used);
82 
83  if (ret != LZMA_STREAM_END || action == LZMA_SYNC_FLUSH)
84  return ret;
85 
86  assert(*in_pos == in_size);
88 
89  // Copy the values into coder->block. The caller
90  // may use this information to construct Index.
91  coder->block->compressed_size = coder->compressed_size;
92  coder->block->uncompressed_size = coder->uncompressed_size;
93 
94  coder->sequence = SEQ_PADDING;
95  }
96 
97  // Fall through
98 
99  case SEQ_PADDING:
100  // Pad Compressed Data to a multiple of four bytes. We can
101  // use coder->compressed_size for this since we don't need
102  // it for anything else anymore.
103  while (coder->compressed_size & 3) {
104  if (*out_pos >= out_size)
105  return LZMA_OK;
106 
107  out[*out_pos] = 0x00;
108  ++*out_pos;
109  ++coder->compressed_size;
110  }
111 
112  if (coder->block->check == LZMA_CHECK_NONE)
113  return LZMA_STREAM_END;
114 
115  lzma_check_finish(&coder->check, coder->block->check);
116 
117  coder->sequence = SEQ_CHECK;
118 
119  // Fall through
120 
121  case SEQ_CHECK: {
122  const size_t check_size = lzma_check_size(coder->block->check);
123  lzma_bufcpy(coder->check.buffer.u8, &coder->pos, check_size,
124  out, out_pos, out_size);
125  if (coder->pos < check_size)
126  return LZMA_OK;
127 
128  memcpy(coder->block->raw_check, coder->check.buffer.u8,
129  check_size);
130  return LZMA_STREAM_END;
131  }
132  }
133 
134  return LZMA_PROG_ERROR;
135 }
136 
137 
138 static void
140 {
141  lzma_block_coder *coder = coder_ptr;
142  lzma_next_end(&coder->next, allocator);
143  lzma_free(coder, allocator);
144  return;
145 }
146 
147 
148 static lzma_ret
150  const lzma_filter *filters lzma_attribute((__unused__)),
151  const lzma_filter *reversed_filters)
152 {
153  lzma_block_coder *coder = coder_ptr;
154 
155  if (coder->sequence != SEQ_CODE)
156  return LZMA_PROG_ERROR;
157 
159  &coder->next, allocator, reversed_filters);
160 }
161 
162 
163 extern lzma_ret
165  lzma_block *block)
166 {
168 
169  if (block == NULL)
170  return LZMA_PROG_ERROR;
171 
172  // The contents of the structure may depend on the version so
173  // check the version first.
174  if (block->version > 1)
175  return LZMA_OPTIONS_ERROR;
176 
177  // If the Check ID is not supported, we cannot calculate the check and
178  // thus not create a proper Block.
179  if ((unsigned int)(block->check) > LZMA_CHECK_ID_MAX)
180  return LZMA_PROG_ERROR;
181 
182  if (!lzma_check_is_supported(block->check))
183  return LZMA_UNSUPPORTED_CHECK;
184 
185  // Allocate and initialize *next->coder if needed.
186  lzma_block_coder *coder = next->coder;
187  if (coder == NULL) {
188  coder = lzma_alloc(sizeof(lzma_block_coder), allocator);
189  if (coder == NULL)
190  return LZMA_MEM_ERROR;
191 
192  next->coder = coder;
193  next->code = &block_encode;
194  next->end = &block_encoder_end;
195  next->update = &block_encoder_update;
196  coder->next = LZMA_NEXT_CODER_INIT;
197  }
198 
199  // Basic initializations
200  coder->sequence = SEQ_CODE;
201  coder->block = block;
202  coder->compressed_size = 0;
203  coder->uncompressed_size = 0;
204  coder->pos = 0;
205 
206  // Initialize the check
207  lzma_check_init(&coder->check, block->check);
208 
209  // Initialize the requested filters.
210  return lzma_raw_encoder_init(&coder->next, allocator, block->filters);
211 }
212 
213 
215 lzma_block_encoder(lzma_stream *strm, lzma_block *block)
216 {
218 
221 
222  return LZMA_OK;
223 }
@ LZMA_CHECK_NONE
Definition: check.h:28
#define LZMA_CHECK_ID_MAX
Maximum valid Check ID.
Definition: check.h:68
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
lzma_ret lzma_block_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, lzma_block *block)
LZMA_API(lzma_ret)
static lzma_ret block_encode(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: block_encoder.c:48
static void block_encoder_end(void *coder_ptr, const lzma_allocator *allocator)
static lzma_ret block_encoder_update(void *coder_ptr, const lzma_allocator *allocator, const lzma_filter *filters lzma_attribute((__unused__)), const lzma_filter *reversed_filters)
Encodes .xz Blocks.
#define COMPRESSED_SIZE_MAX
Biggest Compressed Size value that the Block encoder supports.
Definition: block_encoder.h:40
void lzma_check_finish(lzma_check_state *check, lzma_check type)
Finish the check calculation and store the result to check->buffer.u8.
Definition: check.c:148
void lzma_check_update(lzma_check_state *check, lzma_check type, const uint8_t *buf, size_t size)
Update the check state.
Definition: check.c:117
void lzma_check_init(lzma_check_state *check, lzma_check type)
Initialize *check depending on type.
Definition: check.c:84
lzma_check check
Definition: container.h:292
const lzma_filter * filters
Definition: container.h:315
#define NULL
Definition: cris-opc.c:27
lzma_ret lzma_raw_encoder_init(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter *options)
static lzma_stream strm
Definition: full_flush.c:20
#define restrict
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
#define lzma_attribute(attr)
Definition: lzma.h:259
assert(limit<=UINT32_MAX/2)
unsigned char uint8_t
Definition: sftypes.h:31
Custom functions for memory handling.
Definition: base.h:372
lzma_check_state check
Check of the uncompressed data.
Definition: block_decoder.c:47
enum lzma_block_coder::@643 sequence
lzma_next_coder next
The filters in the chain; initialized with lzma_raw_decoder_init().
Definition: block_decoder.c:26
lzma_block * block
Definition: block_decoder.c:30
size_t pos
Position in the Check field.
Definition: block_encoder.c:40
lzma_vli uncompressed_size
Uncompressed Size calculated while decoding.
Definition: block_decoder.c:36
lzma_vli compressed_size
Compressed Size calculated while decoding.
Definition: block_decoder.c:33
Options for the Block and Block Header encoders and decoders.
Definition: block.h:30
lzma_vli uncompressed_size
Uncompressed Size in bytes.
Definition: block.h:172
uint8_t raw_check[LZMA_CHECK_SIZE_MAX]
Raw value stored in the Check field.
Definition: block.h:217
lzma_filter * filters
Array of filters.
Definition: block.h:200
lzma_check check
Type of integrity Check.
Definition: block.h:93
lzma_vli compressed_size
Size of the Compressed Data in bytes.
Definition: block.h:148
uint32_t version
Block format version.
Definition: block.h:52
Structure to hold internal state of the check being calculated.
Definition: check.h:81
uint8_t u8[64]
Definition: check.h:84
union lzma_check_state::@638 buffer
Buffer to hold the final result and a temporary buffer for SHA256.
Filter options.
Definition: filter.h:43
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(* update)(void *coder, const lzma_allocator *allocator, const lzma_filter *filters, const lzma_filter *reversed_filters)
Definition: common.h:173
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_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.
uint64_t compressed_size
Definition: list.c:105
uint64_t uncompressed_size
Definition: list.c:106
uint64_t lzma_vli
Variable-length integer type.
Definition: vli.h:63
#define LZMA_VLI_MAX
Maximum supported value of a variable-length integer.
Definition: vli.h:34
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_MEM_ERROR
Cannot allocate memory.
Definition: base.h:128
@ 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_OPTIONS_ERROR
Invalid or unsupported options.
Definition: base.h:160
@ LZMA_OK
Operation completed successfully.
Definition: base.h:58
lzma_action
The ‘action’ argument for lzma_code()
Definition: base.h:250
@ 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
void lzma_free(void *ptr, const lzma_allocator *allocator)
Frees memory.
Definition: common.c:78
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)
Definition: common.c:94
lzma_ret lzma_next_filter_update(lzma_next_coder *next, const lzma_allocator *allocator, const lzma_filter *reversed_filters)
Definition: common.c:127
void lzma_next_end(lzma_next_coder *next, const lzma_allocator *allocator)
Definition: common.c:145