aboutsummaryrefslogtreecommitdiff
path: root/src/liblzma/common/alone_decoder.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/liblzma/common/alone_decoder.c')
-rw-r--r--src/liblzma/common/alone_decoder.c49
1 files changed, 31 insertions, 18 deletions
diff --git a/src/liblzma/common/alone_decoder.c b/src/liblzma/common/alone_decoder.c
index 062f6fab..006740f4 100644
--- a/src/liblzma/common/alone_decoder.c
+++ b/src/liblzma/common/alone_decoder.c
@@ -19,6 +19,7 @@
#include "alone_decoder.h"
#include "lzma_decoder.h"
+#include "lz_decoder.h"
struct lzma_coder_s {
@@ -38,6 +39,9 @@ struct lzma_coder_s {
/// Uncompressed size decoded from the header
lzma_vli uncompressed_size;
+ /// Memory usage limit
+ uint64_t memlimit;
+
/// Options decoded from the header needed to initialize
/// the LZMA decoder
lzma_options_lzma options;
@@ -56,7 +60,7 @@ alone_decode(lzma_coder *coder,
&& (coder->sequence == SEQ_CODE || *in_pos < in_size))
switch (coder->sequence) {
case SEQ_PROPERTIES:
- if (lzma_lzma_decode_properties(&coder->options, in[*in_pos]))
+ if (lzma_lzma_lclppb_decode(&coder->options, in[*in_pos]))
return LZMA_FORMAT_ERROR;
coder->sequence = SEQ_DICTIONARY_SIZE;
@@ -69,8 +73,6 @@ alone_decode(lzma_coder *coder,
if (++coder->pos == 4) {
if (coder->options.dictionary_size
- < LZMA_DICTIONARY_SIZE_MIN
- || coder->options.dictionary_size
> LZMA_DICTIONARY_SIZE_MAX)
return LZMA_FORMAT_ERROR;
@@ -119,7 +121,20 @@ alone_decode(lzma_coder *coder,
break;
case SEQ_CODER_INIT: {
- // Two is enough because there won't be implicit filters.
+ // FIXME It is unfair that this doesn't add a fixed amount
+ // like lzma_memusage_common() does.
+ const uint64_t memusage
+ = lzma_lzma_decoder_memusage(&coder->options);
+
+ // Use LZMA_PROG_ERROR since LZMA_Alone decoder cannot be
+ // built without LZMA support.
+ // FIXME TODO Make the above comment true.
+ if (memusage == UINT64_MAX)
+ return LZMA_PROG_ERROR;
+
+ if (memusage > coder->memlimit)
+ return LZMA_MEMLIMIT_ERROR;
+
lzma_filter_info filters[2] = {
{
.init = &lzma_lzma_decoder_init,
@@ -135,7 +150,7 @@ alone_decode(lzma_coder *coder,
return ret;
// Use a hack to set the uncompressed size.
- lzma_lzma_decoder_uncompressed_size(&coder->next,
+ lzma_lz_decoder_uncompressed(coder->next.coder,
coder->uncompressed_size);
coder->sequence = SEQ_CODE;
@@ -160,15 +175,18 @@ alone_decode(lzma_coder *coder,
static void
alone_decoder_end(lzma_coder *coder, lzma_allocator *allocator)
{
- lzma_next_coder_end(&coder->next, allocator);
+ lzma_next_end(&coder->next, allocator);
lzma_free(coder, allocator);
return;
}
-static lzma_ret
-alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator)
+extern lzma_ret
+lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator,
+ uint64_t memlimit)
{
+ lzma_next_coder_init(lzma_alone_decoder_init, next, allocator);
+
if (next->coder == NULL) {
next->coder = lzma_alloc(sizeof(lzma_coder), allocator);
if (next->coder == NULL)
@@ -183,25 +201,20 @@ alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator)
next->coder->pos = 0;
next->coder->options.dictionary_size = 0;
next->coder->uncompressed_size = 0;
+ next->coder->memlimit = memlimit;
return LZMA_OK;
}
-extern lzma_ret
-lzma_alone_decoder_init(lzma_next_coder *next, lzma_allocator *allocator)
-{
- lzma_next_coder_init0(alone_decoder_init, next, allocator);
-}
-
-
extern LZMA_API lzma_ret
-lzma_alone_decoder(lzma_stream *strm)
+lzma_alone_decoder(lzma_stream *strm, uint64_t memlimit)
{
- lzma_next_strm_init0(strm, alone_decoder_init);
+ lzma_next_strm_init(lzma_alone_decoder_init, strm, memlimit);
strm->internal->supported_actions[LZMA_RUN] = true;
- strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true;
+// strm->internal->supported_actions[LZMA_SYNC_FLUSH] = true; FIXME
+ strm->internal->supported_actions[LZMA_FINISH] = true;
return LZMA_OK;
}