]> git.ipfire.org Git - thirdparty/xz.git/commitdiff
liblzma: Stream decoder: Fix restarting after LZMA_MEMLIMIT_ERROR.
authorLasse Collin <lasse.collin@tukaani.org>
Wed, 28 Sep 2022 08:05:15 +0000 (11:05 +0300)
committerLasse Collin <lasse.collin@tukaani.org>
Wed, 28 Sep 2022 08:05:15 +0000 (11:05 +0300)
If lzma_code() returns LZMA_MEMLIMIT_ERROR it is now possible
to use lzma_memlimit_set() to increase the limit and continue
decoding. This was supposed to work from the beginning but
there was a bug. With other decoders (.lzma or threaded .xz)
this already worked correctly.

src/liblzma/common/stream_decoder.c

index 0c64605275843ee8778a2c5126c3026d6fc3e62c..6885d0c7c8cf1eacfe41a5b4e06e409903928c76 100644 (file)
@@ -18,7 +18,8 @@ typedef struct {
        enum {
                SEQ_STREAM_HEADER,
                SEQ_BLOCK_HEADER,
-               SEQ_BLOCK,
+               SEQ_BLOCK_INIT,
+               SEQ_BLOCK_RUN,
                SEQ_INDEX,
                SEQ_STREAM_FOOTER,
                SEQ_STREAM_PADDING,
@@ -185,6 +186,15 @@ stream_decode(void *coder_ptr, const lzma_allocator *allocator,
                        return LZMA_OK;
 
                coder->pos = 0;
+               coder->sequence = SEQ_BLOCK_INIT;
+       }
+
+       // Fall through
+
+       case SEQ_BLOCK_INIT: {
+               // Checking memusage and doing the initialization needs
+               // its own sequence point because we need to be able to
+               // retry if we return LZMA_MEMLIMIT_ERROR.
 
                // Version 1 is needed to support the .ignore_check option.
                coder->block_options.version = 1;
@@ -243,12 +253,12 @@ stream_decode(void *coder_ptr, const lzma_allocator *allocator,
                if (ret != LZMA_OK)
                        return ret;
 
-               coder->sequence = SEQ_BLOCK;
+               coder->sequence = SEQ_BLOCK_RUN;
        }
 
        // Fall through
 
-       case SEQ_BLOCK: {
+       case SEQ_BLOCK_RUN: {
                const lzma_ret ret = coder->block_decoder.code(
                                coder->block_decoder.coder, allocator,
                                in, in_pos, in_size, out, out_pos, out_size,