28 #define MEMORY_LIMIT (16 * 1024 * 1024)
40 case BEST_COMPRESSION:
41 case HIGH_COMPRESSION:
return 6;
42 case MEDIUM_COMPRESSION:
return 4;
43 case LOW_COMPRESSION:
return 2;
49 lzma_error_str(lzma_ret error)
53 return "Operation completed successfully";
55 return "End of stream";
57 return "Input stream lacks integrity check";
58 case LZMA_UNSUPPORTED_CHECK:
59 return "Unable to calculate integrity check";
61 return "Integrity check available";
63 return "Unable to allocate memory";
64 case LZMA_MEMLIMIT_ERROR:
65 return "Memory limit reached";
66 case LZMA_FORMAT_ERROR:
67 return "Unknown file format";
68 case LZMA_OPTIONS_ERROR:
69 return "Unsupported options";
71 return "Corrupt input data";
73 return "Unable to progress";
75 return "Programming error";
77 return "Unknown LZMA error";
99 return lzma_version_string();
111 return LZMA_VERSION_STRING;
141 uint64_t memory_usage;
144 memory_usage = lzma_easy_encoder_memusage(
memory_level(level));
146 memory_usage = lzma_easy_decoder_memusage(
memory_level(level));
148 if (memory_usage == UINT64_MAX) {
150 log_warn(
LD_GENERAL,
"Unsupported compression level passed to LZMA %s",
151 compress ?
"encoder" :
"decoder");
157 memory_usage = SIZE_MAX;
161 return (
size_t)memory_usage;
183 lzma_options_lzma stream_options;
190 result->
allocation = tor_lzma_state_size_precalc(compress, level);
195 retval = lzma_alone_encoder(&result->stream, &stream_options);
197 if (retval != LZMA_OK) {
199 log_warn(
LD_GENERAL,
"Error from LZMA encoder: %s (%u).",
200 lzma_error_str(retval), retval);
205 retval = lzma_alone_decoder(&result->stream,
MEMORY_LIMIT);
207 if (retval != LZMA_OK) {
209 log_warn(
LD_GENERAL,
"Error from LZMA decoder: %s (%u).",
210 lzma_error_str(retval), retval);
246 char **out,
size_t *out_len,
247 const char **in,
size_t *in_len,
258 state->stream.next_in = (
unsigned char *)*in;
259 state->stream.avail_in = *in_len;
260 state->stream.next_out = (
unsigned char *)*out;
261 state->stream.avail_out = *out_len;
263 action = finish ? LZMA_FINISH : LZMA_RUN;
265 retval = lzma_code(&state->stream, action);
267 state->
input_so_far += state->stream.next_in - ((
unsigned char *)*in);
268 state->
output_so_far += state->stream.next_out - ((
unsigned char *)*out);
270 *out = (
char *)state->stream.next_out;
271 *out_len = state->stream.avail_out;
272 *in = (
const char *)state->stream.next_in;
273 *in_len = state->stream.avail_in;
278 log_warn(
LD_DIR,
"Possible compression bomb; abandoning stream.");
279 return TOR_COMPRESS_ERROR;
284 if (state->stream.avail_out == 0 || finish)
285 return TOR_COMPRESS_BUFFER_FULL;
287 return TOR_COMPRESS_OK;
290 if (state->stream.avail_in == 0 && !finish)
291 return TOR_COMPRESS_OK;
293 return TOR_COMPRESS_BUFFER_FULL;
295 case LZMA_STREAM_END:
296 return TOR_COMPRESS_DONE;
301 case LZMA_UNSUPPORTED_CHECK:
304 case LZMA_MEMLIMIT_ERROR:
305 case LZMA_FORMAT_ERROR:
306 case LZMA_OPTIONS_ERROR:
307 case LZMA_DATA_ERROR:
308 case LZMA_PROG_ERROR:
310 log_warn(
LD_GENERAL,
"LZMA %s didn't finish: %s.",
311 state->
compress ?
"compression" :
"decompression",
312 lzma_error_str(retval));
313 return TOR_COMPRESS_ERROR;
322 return TOR_COMPRESS_ERROR;
336 lzma_end(&state->stream);
void atomic_counter_init(atomic_counter_t *counter)
void atomic_counter_sub(atomic_counter_t *counter, size_t sub)
void atomic_counter_add(atomic_counter_t *counter, size_t add)
size_t atomic_counter_get(atomic_counter_t *counter)
int tor_compress_is_compression_bomb(size_t size_in, size_t size_out)
int tor_lzma_method_supported(void)
const char * tor_lzma_get_version_str(void)
static atomic_counter_t total_lzma_allocation
const char * tor_lzma_get_header_version_str(void)
tor_compress_output_t tor_lzma_compress_process(tor_lzma_compress_state_t *state, char **out, size_t *out_len, const char **in, size_t *in_len, int finish)
tor_lzma_compress_state_t * tor_lzma_compress_new(int compress, compress_method_t method, compression_level_t level)
size_t tor_lzma_compress_state_size(const tor_lzma_compress_state_t *state)
size_t tor_lzma_get_total_allocation(void)
void tor_lzma_compress_free_(tor_lzma_compress_state_t *state)
Header for compress_lzma.c.
static int memory_level(compression_level_t level)
Headers for util_malloc.c.
Macros to manage assertions, fatal and non-fatal.