aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/liblzma/lzma/lzma2_encoder.c5
-rw-r--r--src/liblzma/lzma/lzma_encoder.c44
-rw-r--r--src/liblzma/lzma/lzma_encoder.h2
3 files changed, 35 insertions, 16 deletions
diff --git a/src/liblzma/lzma/lzma2_encoder.c b/src/liblzma/lzma/lzma2_encoder.c
index 757b871d..46912c3f 100644
--- a/src/liblzma/lzma/lzma2_encoder.c
+++ b/src/liblzma/lzma/lzma2_encoder.c
@@ -182,6 +182,8 @@ lzma2_encode(lzma_coder *restrict coder, lzma_mf *restrict mf,
|| coder->opt_cur.lp != coder->opt_new->lp
|| coder->opt_cur.pb != coder->opt_new->pb)) {
// Options have been changed, copy them to opt_cur.
+ // These get validated as part of
+ // lzma_lzma_encoder_reset() below.
coder->opt_cur.lc = coder->opt_new->lc;
coder->opt_cur.lp = coder->opt_new->lp;
coder->opt_cur.pb = coder->opt_new->pb;
@@ -193,7 +195,8 @@ lzma2_encode(lzma_coder *restrict coder, lzma_mf *restrict mf,
}
if (coder->need_state_reset)
- lzma_lzma_encoder_reset(coder->lzma, &coder->opt_cur);
+ return_if_error(lzma_lzma_encoder_reset(
+ coder->lzma, &coder->opt_cur));
coder->uncompressed_size = 0;
coder->compressed_size = 0;
diff --git a/src/liblzma/lzma/lzma_encoder.c b/src/liblzma/lzma/lzma_encoder.c
index 2f81bedc..57ba87f3 100644
--- a/src/liblzma/lzma/lzma_encoder.c
+++ b/src/liblzma/lzma/lzma_encoder.c
@@ -422,11 +422,24 @@ lzma_encode(lzma_coder *restrict coder, lzma_mf *restrict mf,
// Initialization //
////////////////////
+static bool
+is_options_valid(const lzma_options_lzma *options)
+{
+ // Validate some of the options. LZ encoder validates nice_len too
+ // but we need a valid value here earlier.
+ return is_lclppb_valid(options)
+ && options->nice_len >= MATCH_LEN_MIN
+ && options->nice_len <= MATCH_LEN_MAX
+ && (options->mode == LZMA_MODE_FAST
+ || options->mode == LZMA_MODE_NORMAL);
+}
+
+
static void
set_lz_options(lzma_lz_options *lz_options, const lzma_options_lzma *options)
{
- // LZ encoder initialization does the validation, also when just
- // calculating memory usage, so we don't need to validate here.
+ // LZ encoder initialization does the validation for these so we
+ // don't need to validate here.
lz_options->before_size = OPTS;
lz_options->dict_size = options->dict_size;
lz_options->after_size = LOOP_INPUT_MAX;
@@ -436,6 +449,7 @@ set_lz_options(lzma_lz_options *lz_options, const lzma_options_lzma *options)
lz_options->depth = options->depth;
lz_options->preset_dict = options->preset_dict;
lz_options->preset_dict_size = options->preset_dict_size;
+ return;
}
@@ -462,10 +476,11 @@ length_encoder_reset(lzma_length_encoder *lencoder,
}
-extern void
+extern lzma_ret
lzma_lzma_encoder_reset(lzma_coder *coder, const lzma_options_lzma *options)
{
- assert(!coder->is_flushed);
+ if (!is_options_valid(options))
+ return LZMA_OPTIONS_ERROR;
coder->pos_mask = (1U << options->pb) - 1;
coder->literal_context_bits = options->lc;
@@ -528,6 +543,8 @@ lzma_lzma_encoder_reset(lzma_coder *coder, const lzma_options_lzma *options)
coder->opts_end_index = 0;
coder->opts_current_index = 0;
+
+ return LZMA_OK;
}
@@ -535,6 +552,7 @@ extern lzma_ret
lzma_lzma_encoder_create(lzma_coder **coder_ptr, lzma_allocator *allocator,
const lzma_options_lzma *options, lzma_lz_options *lz_options)
{
+ // Allocate lzma_coder if it wasn't already allocated.
if (*coder_ptr == NULL) {
*coder_ptr = lzma_alloc(sizeof(lzma_coder), allocator);
if (*coder_ptr == NULL)
@@ -543,13 +561,10 @@ lzma_lzma_encoder_create(lzma_coder **coder_ptr, lzma_allocator *allocator,
lzma_coder *coder = *coder_ptr;
- // Validate some of the options. LZ encoder validates fast_bytes too
- // but we need a valid value here earlier.
- if (!is_lclppb_valid(options) || options->nice_len < MATCH_LEN_MIN
- || options->nice_len > MATCH_LEN_MAX)
- return LZMA_OPTIONS_ERROR;
-
- // Set compression mode.
+ // Set compression mode. We haven't validates the options yet,
+ // but it's OK here, since nothing bad happens with invalid
+ // options in the code below, and they will get rejected by
+ // lzma_lzma_encoder_reset() call at the end of this function.
switch (options->mode) {
case LZMA_MODE_FAST:
coder->fast_mode = true;
@@ -581,11 +596,9 @@ lzma_lzma_encoder_create(lzma_coder **coder_ptr, lzma_allocator *allocator,
coder->is_initialized = false;
coder->is_flushed = false;
- lzma_lzma_encoder_reset(coder, options);
-
set_lz_options(lz_options, options);
- return LZMA_OK;
+ return lzma_lzma_encoder_reset(coder, options);
}
@@ -611,6 +624,9 @@ lzma_lzma_encoder_init(lzma_next_coder *next, lzma_allocator *allocator,
extern uint64_t
lzma_lzma_encoder_memusage(const void *options)
{
+ if (!is_options_valid(options))
+ return UINT64_MAX;
+
lzma_lz_options lz_options;
set_lz_options(&lz_options, options);
diff --git a/src/liblzma/lzma/lzma_encoder.h b/src/liblzma/lzma/lzma_encoder.h
index e270cc27..c9f7d005 100644
--- a/src/liblzma/lzma/lzma_encoder.h
+++ b/src/liblzma/lzma/lzma_encoder.h
@@ -55,7 +55,7 @@ extern lzma_ret lzma_lzma_encoder_create(
/// Resets an already initialized LZMA encoder; this is used by LZMA2.
-extern void lzma_lzma_encoder_reset(
+extern lzma_ret lzma_lzma_encoder_reset(
lzma_coder *coder, const lzma_options_lzma *options);