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

Single-call .xz Stream encoder. More...

#include "index.h"

Go to the source code of this file.

Macros

#define INDEX_BOUND   ((1 + 1 + 2 * LZMA_VLI_BYTES_MAX + 4 + 3) & ~3)
 
#define HEADERS_BOUND   (2 * LZMA_STREAM_HEADER_SIZE + INDEX_BOUND)
 Stream Header, Stream Footer, and Index. More...
 

Functions

 LZMA_API (size_t)
 Calculate maximum output size for single-call Block encoding. More...
 
 LZMA_API (lzma_ret)
 

Detailed Description

Single-call .xz Stream encoder.

Definition in file stream_buffer_encoder.c.

Macro Definition Documentation

◆ HEADERS_BOUND

#define HEADERS_BOUND   (2 * LZMA_STREAM_HEADER_SIZE + INDEX_BOUND)

Stream Header, Stream Footer, and Index.

Definition at line 22 of file stream_buffer_encoder.c.

◆ INDEX_BOUND

#define INDEX_BOUND   ((1 + 1 + 2 * LZMA_VLI_BYTES_MAX + 4 + 3) & ~3)

Maximum size of Index that has exactly one Record. Index Indicator + Number of Records + Record + CRC32 rounded up to the next multiple of four.

Definition at line 19 of file stream_buffer_encoder.c.

Function Documentation

◆ LZMA_API() [1/2]

LZMA_API ( lzma_ret  )

Definition at line 43 of file stream_buffer_encoder.c.

48 {
49  // Sanity checks
50  if (filters == NULL || (unsigned int)(check) > LZMA_CHECK_ID_MAX
51  || (in == NULL && in_size != 0) || out == NULL
52  || out_pos_ptr == NULL || *out_pos_ptr > out_size)
53  return LZMA_PROG_ERROR;
54 
55  if (!lzma_check_is_supported(check))
57 
58  // Note for the paranoids: Index encoder prevents the Stream from
59  // getting too big and still being accepted with LZMA_OK, and Block
60  // encoder catches if the input is too big. So we don't need to
61  // separately check if the buffers are too big.
62 
63  // Use a local copy. We update *out_pos_ptr only if everything
64  // succeeds.
65  size_t out_pos = *out_pos_ptr;
66 
67  // Check that there's enough space for both Stream Header and
68  // Stream Footer.
69  if (out_size - out_pos <= 2 * LZMA_STREAM_HEADER_SIZE)
70  return LZMA_BUF_ERROR;
71 
72  // Reserve space for Stream Footer so we don't need to check for
73  // available space again before encoding Stream Footer.
74  out_size -= LZMA_STREAM_HEADER_SIZE;
75 
76  // Encode the Stream Header.
77  lzma_stream_flags stream_flags = {
78  .version = 0,
79  .check = check,
80  };
81 
82  if (lzma_stream_header_encode(&stream_flags, out + out_pos)
83  != LZMA_OK)
84  return LZMA_PROG_ERROR;
85 
87 
88  // Encode a Block but only if there is at least one byte of input.
89  lzma_block block = {
90  .version = 0,
91  .check = check,
92  .filters = filters,
93  };
94 
95  if (in_size > 0)
96  return_if_error(lzma_block_buffer_encode(&block, allocator,
97  in, in_size, out, &out_pos, out_size));
98 
99  // Index
100  {
101  // Create an Index. It will have one Record if there was
102  // at least one byte of input to encode. Otherwise the
103  // Index will be empty.
104  lzma_index *i = lzma_index_init(allocator);
105  if (i == NULL)
106  return LZMA_MEM_ERROR;
107 
108  lzma_ret ret = LZMA_OK;
109 
110  if (in_size > 0)
111  ret = lzma_index_append(i, allocator,
112  lzma_block_unpadded_size(&block),
113  block.uncompressed_size);
114 
115  // If adding the Record was successful, encode the Index
116  // and get its size which will be stored into Stream Footer.
117  if (ret == LZMA_OK) {
118  ret = lzma_index_buffer_encode(
119  i, out, &out_pos, out_size);
120 
121  stream_flags.backward_size = lzma_index_size(i);
122  }
123 
124  lzma_index_end(i, allocator);
125 
126  if (ret != LZMA_OK)
127  return ret;
128  }
129 
130  // Stream Footer. We have already reserved space for this.
131  if (lzma_stream_footer_encode(&stream_flags, out + out_pos)
132  != LZMA_OK)
133  return LZMA_PROG_ERROR;
134 
136 
137  // Everything went fine, make the new output position available
138  // to the application.
139  *out_pos_ptr = out_pos;
140  return LZMA_OK;
141 }
#define LZMA_CHECK_ID_MAX
Maximum valid Check ID.
Definition: check.h:68
lzma_index ** i
Definition: index.h:629
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_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_check check
Definition: container.h:292
const lzma_filter * filters
Definition: container.h:315
#define NULL
Definition: cris-opc.c:27
#define LZMA_STREAM_HEADER_SIZE
Size of Stream Header and Stream Footer.
Definition: stream_flags.h:27
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
uint32_t version
Block format version.
Definition: block.h:52
Options for encoding/decoding Stream Header and Stream Footer.
Definition: stream_flags.h:33
uint32_t version
Stream Flags format version.
Definition: stream_flags.h:51
lzma_vli backward_size
Backward Size.
Definition: stream_flags.h:69
#define return_if_error(expr)
Return if expression doesn't evaluate to LZMA_OK.
Definition: common.h:278
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_UNSUPPORTED_CHECK
Cannot calculate the integrity check.
Definition: base.h:90
@ LZMA_BUF_ERROR
No progress is possible.
Definition: base.h:191
@ LZMA_OK
Operation completed successfully.
Definition: base.h:58

References allocator, lzma_stream_flags::backward_size, check, filters, i, in, in_size, LZMA_BUF_ERROR, LZMA_CHECK_ID_MAX, LZMA_MEM_ERROR, LZMA_OK, LZMA_PROG_ERROR, LZMA_STREAM_HEADER_SIZE, LZMA_UNSUPPORTED_CHECK, NULL, out, out_pos, return_if_error, lzma_block::uncompressed_size, lzma_block::version, and lzma_stream_flags::version.

◆ LZMA_API() [2/2]

LZMA_API ( size_t  )

Calculate maximum output size for single-call Block encoding.

Calculate output buffer size for single-call Stream encoder.

This is equivalent to lzma_stream_buffer_bound() but for .xz Blocks. See the documentation of lzma_stream_buffer_bound().

Definition at line 25 of file stream_buffer_encoder.c.

27 {
28  // Get the maximum possible size of a Block.
29  const size_t block_bound = lzma_block_buffer_bound(uncompressed_size);
30  if (block_bound == 0)
31  return 0;
32 
33  // Catch the possible integer overflow and also prevent the size of
34  // the Stream exceeding LZMA_VLI_MAX (theoretically possible on
35  // 64-bit systems).
36  if (my_min(SIZE_MAX, LZMA_VLI_MAX) - block_bound < HEADERS_BOUND)
37  return 0;
38 
39  return block_bound + HEADERS_BOUND;
40 }
#define SIZE_MAX
#define HEADERS_BOUND
Stream Header, Stream Footer, and Index.
uint64_t uncompressed_size
Definition: list.c:106
#define my_min(x, y)
Definition: sysdefs.h:185
#define LZMA_VLI_MAX
Maximum supported value of a variable-length integer.
Definition: vli.h:34

References HEADERS_BOUND, lzma_block_buffer_bound64(), LZMA_VLI_MAX, my_min, SIZE_MAX, and uncompressed_size.