mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-25 20:14:25 +08:00
aaa2975f2b
MicroLZMA is a yet another header format variant where the first byte of a raw LZMA stream (without the end of stream marker) has been replaced with a bitwise-negation of the lc/lp/pb properties byte. MicroLZMA was created to be used in EROFS but can be used by other things too where wasting minimal amount of space for headers is important. This is implemented using most of the LZMA2 code as is so the amount of new code is small. The API has a few extra features compared to the XZ decoder. On the other hand, the API lacks XZ_BUF_ERROR support which is important to take into account when using this API. MicroLZMA doesn't support BCJ filters. In theory they could be added later as there are many unused/reserved values for the first byte of the compressed stream but in practice it is somewhat unlikely to happen due to a few implementation reasons. Link: https://lore.kernel.org/r/20211010213145.17462-5-xiang@kernel.org Signed-off-by: Lasse Collin <lasse.collin@tukaani.org> Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
1345 lines
33 KiB
C
1345 lines
33 KiB
C
/*
|
|
* LZMA2 decoder
|
|
*
|
|
* Authors: Lasse Collin <lasse.collin@tukaani.org>
|
|
* Igor Pavlov <https://7-zip.org/>
|
|
*
|
|
* This file has been put into the public domain.
|
|
* You can do whatever you want with this file.
|
|
*/
|
|
|
|
#include "xz_private.h"
|
|
#include "xz_lzma2.h"
|
|
|
|
/*
|
|
* Range decoder initialization eats the first five bytes of each LZMA chunk.
|
|
*/
|
|
#define RC_INIT_BYTES 5
|
|
|
|
/*
|
|
* Minimum number of usable input buffer to safely decode one LZMA symbol.
|
|
* The worst case is that we decode 22 bits using probabilities and 26
|
|
* direct bits. This may decode at maximum of 20 bytes of input. However,
|
|
* lzma_main() does an extra normalization before returning, thus we
|
|
* need to put 21 here.
|
|
*/
|
|
#define LZMA_IN_REQUIRED 21
|
|
|
|
/*
|
|
* Dictionary (history buffer)
|
|
*
|
|
* These are always true:
|
|
* start <= pos <= full <= end
|
|
* pos <= limit <= end
|
|
*
|
|
* In multi-call mode, also these are true:
|
|
* end == size
|
|
* size <= size_max
|
|
* allocated <= size
|
|
*
|
|
* Most of these variables are size_t to support single-call mode,
|
|
* in which the dictionary variables address the actual output
|
|
* buffer directly.
|
|
*/
|
|
struct dictionary {
|
|
/* Beginning of the history buffer */
|
|
uint8_t *buf;
|
|
|
|
/* Old position in buf (before decoding more data) */
|
|
size_t start;
|
|
|
|
/* Position in buf */
|
|
size_t pos;
|
|
|
|
/*
|
|
* How full dictionary is. This is used to detect corrupt input that
|
|
* would read beyond the beginning of the uncompressed stream.
|
|
*/
|
|
size_t full;
|
|
|
|
/* Write limit; we don't write to buf[limit] or later bytes. */
|
|
size_t limit;
|
|
|
|
/*
|
|
* End of the dictionary buffer. In multi-call mode, this is
|
|
* the same as the dictionary size. In single-call mode, this
|
|
* indicates the size of the output buffer.
|
|
*/
|
|
size_t end;
|
|
|
|
/*
|
|
* Size of the dictionary as specified in Block Header. This is used
|
|
* together with "full" to detect corrupt input that would make us
|
|
* read beyond the beginning of the uncompressed stream.
|
|
*/
|
|
uint32_t size;
|
|
|
|
/*
|
|
* Maximum allowed dictionary size in multi-call mode.
|
|
* This is ignored in single-call mode.
|
|
*/
|
|
uint32_t size_max;
|
|
|
|
/*
|
|
* Amount of memory currently allocated for the dictionary.
|
|
* This is used only with XZ_DYNALLOC. (With XZ_PREALLOC,
|
|
* size_max is always the same as the allocated size.)
|
|
*/
|
|
uint32_t allocated;
|
|
|
|
/* Operation mode */
|
|
enum xz_mode mode;
|
|
};
|
|
|
|
/* Range decoder */
|
|
struct rc_dec {
|
|
uint32_t range;
|
|
uint32_t code;
|
|
|
|
/*
|
|
* Number of initializing bytes remaining to be read
|
|
* by rc_read_init().
|
|
*/
|
|
uint32_t init_bytes_left;
|
|
|
|
/*
|
|
* Buffer from which we read our input. It can be either
|
|
* temp.buf or the caller-provided input buffer.
|
|
*/
|
|
const uint8_t *in;
|
|
size_t in_pos;
|
|
size_t in_limit;
|
|
};
|
|
|
|
/* Probabilities for a length decoder. */
|
|
struct lzma_len_dec {
|
|
/* Probability of match length being at least 10 */
|
|
uint16_t choice;
|
|
|
|
/* Probability of match length being at least 18 */
|
|
uint16_t choice2;
|
|
|
|
/* Probabilities for match lengths 2-9 */
|
|
uint16_t low[POS_STATES_MAX][LEN_LOW_SYMBOLS];
|
|
|
|
/* Probabilities for match lengths 10-17 */
|
|
uint16_t mid[POS_STATES_MAX][LEN_MID_SYMBOLS];
|
|
|
|
/* Probabilities for match lengths 18-273 */
|
|
uint16_t high[LEN_HIGH_SYMBOLS];
|
|
};
|
|
|
|
struct lzma_dec {
|
|
/* Distances of latest four matches */
|
|
uint32_t rep0;
|
|
uint32_t rep1;
|
|
uint32_t rep2;
|
|
uint32_t rep3;
|
|
|
|
/* Types of the most recently seen LZMA symbols */
|
|
enum lzma_state state;
|
|
|
|
/*
|
|
* Length of a match. This is updated so that dict_repeat can
|
|
* be called again to finish repeating the whole match.
|
|
*/
|
|
uint32_t len;
|
|
|
|
/*
|
|
* LZMA properties or related bit masks (number of literal
|
|
* context bits, a mask derived from the number of literal
|
|
* position bits, and a mask derived from the number
|
|
* position bits)
|
|
*/
|
|
uint32_t lc;
|
|
uint32_t literal_pos_mask; /* (1 << lp) - 1 */
|
|
uint32_t pos_mask; /* (1 << pb) - 1 */
|
|
|
|
/* If 1, it's a match. Otherwise it's a single 8-bit literal. */
|
|
uint16_t is_match[STATES][POS_STATES_MAX];
|
|
|
|
/* If 1, it's a repeated match. The distance is one of rep0 .. rep3. */
|
|
uint16_t is_rep[STATES];
|
|
|
|
/*
|
|
* If 0, distance of a repeated match is rep0.
|
|
* Otherwise check is_rep1.
|
|
*/
|
|
uint16_t is_rep0[STATES];
|
|
|
|
/*
|
|
* If 0, distance of a repeated match is rep1.
|
|
* Otherwise check is_rep2.
|
|
*/
|
|
uint16_t is_rep1[STATES];
|
|
|
|
/* If 0, distance of a repeated match is rep2. Otherwise it is rep3. */
|
|
uint16_t is_rep2[STATES];
|
|
|
|
/*
|
|
* If 1, the repeated match has length of one byte. Otherwise
|
|
* the length is decoded from rep_len_decoder.
|
|
*/
|
|
uint16_t is_rep0_long[STATES][POS_STATES_MAX];
|
|
|
|
/*
|
|
* Probability tree for the highest two bits of the match
|
|
* distance. There is a separate probability tree for match
|
|
* lengths of 2 (i.e. MATCH_LEN_MIN), 3, 4, and [5, 273].
|
|
*/
|
|
uint16_t dist_slot[DIST_STATES][DIST_SLOTS];
|
|
|
|
/*
|
|
* Probility trees for additional bits for match distance
|
|
* when the distance is in the range [4, 127].
|
|
*/
|
|
uint16_t dist_special[FULL_DISTANCES - DIST_MODEL_END];
|
|
|
|
/*
|
|
* Probability tree for the lowest four bits of a match
|
|
* distance that is equal to or greater than 128.
|
|
*/
|
|
uint16_t dist_align[ALIGN_SIZE];
|
|
|
|
/* Length of a normal match */
|
|
struct lzma_len_dec match_len_dec;
|
|
|
|
/* Length of a repeated match */
|
|
struct lzma_len_dec rep_len_dec;
|
|
|
|
/* Probabilities of literals */
|
|
uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE];
|
|
};
|
|
|
|
struct lzma2_dec {
|
|
/* Position in xz_dec_lzma2_run(). */
|
|
enum lzma2_seq {
|
|
SEQ_CONTROL,
|
|
SEQ_UNCOMPRESSED_1,
|
|
SEQ_UNCOMPRESSED_2,
|
|
SEQ_COMPRESSED_0,
|
|
SEQ_COMPRESSED_1,
|
|
SEQ_PROPERTIES,
|
|
SEQ_LZMA_PREPARE,
|
|
SEQ_LZMA_RUN,
|
|
SEQ_COPY
|
|
} sequence;
|
|
|
|
/* Next position after decoding the compressed size of the chunk. */
|
|
enum lzma2_seq next_sequence;
|
|
|
|
/* Uncompressed size of LZMA chunk (2 MiB at maximum) */
|
|
uint32_t uncompressed;
|
|
|
|
/*
|
|
* Compressed size of LZMA chunk or compressed/uncompressed
|
|
* size of uncompressed chunk (64 KiB at maximum)
|
|
*/
|
|
uint32_t compressed;
|
|
|
|
/*
|
|
* True if dictionary reset is needed. This is false before
|
|
* the first chunk (LZMA or uncompressed).
|
|
*/
|
|
bool need_dict_reset;
|
|
|
|
/*
|
|
* True if new LZMA properties are needed. This is false
|
|
* before the first LZMA chunk.
|
|
*/
|
|
bool need_props;
|
|
|
|
#ifdef XZ_DEC_MICROLZMA
|
|
bool pedantic_microlzma;
|
|
#endif
|
|
};
|
|
|
|
struct xz_dec_lzma2 {
|
|
/*
|
|
* The order below is important on x86 to reduce code size and
|
|
* it shouldn't hurt on other platforms. Everything up to and
|
|
* including lzma.pos_mask are in the first 128 bytes on x86-32,
|
|
* which allows using smaller instructions to access those
|
|
* variables. On x86-64, fewer variables fit into the first 128
|
|
* bytes, but this is still the best order without sacrificing
|
|
* the readability by splitting the structures.
|
|
*/
|
|
struct rc_dec rc;
|
|
struct dictionary dict;
|
|
struct lzma2_dec lzma2;
|
|
struct lzma_dec lzma;
|
|
|
|
/*
|
|
* Temporary buffer which holds small number of input bytes between
|
|
* decoder calls. See lzma2_lzma() for details.
|
|
*/
|
|
struct {
|
|
uint32_t size;
|
|
uint8_t buf[3 * LZMA_IN_REQUIRED];
|
|
} temp;
|
|
};
|
|
|
|
/**************
|
|
* Dictionary *
|
|
**************/
|
|
|
|
/*
|
|
* Reset the dictionary state. When in single-call mode, set up the beginning
|
|
* of the dictionary to point to the actual output buffer.
|
|
*/
|
|
static void dict_reset(struct dictionary *dict, struct xz_buf *b)
|
|
{
|
|
if (DEC_IS_SINGLE(dict->mode)) {
|
|
dict->buf = b->out + b->out_pos;
|
|
dict->end = b->out_size - b->out_pos;
|
|
}
|
|
|
|
dict->start = 0;
|
|
dict->pos = 0;
|
|
dict->limit = 0;
|
|
dict->full = 0;
|
|
}
|
|
|
|
/* Set dictionary write limit */
|
|
static void dict_limit(struct dictionary *dict, size_t out_max)
|
|
{
|
|
if (dict->end - dict->pos <= out_max)
|
|
dict->limit = dict->end;
|
|
else
|
|
dict->limit = dict->pos + out_max;
|
|
}
|
|
|
|
/* Return true if at least one byte can be written into the dictionary. */
|
|
static inline bool dict_has_space(const struct dictionary *dict)
|
|
{
|
|
return dict->pos < dict->limit;
|
|
}
|
|
|
|
/*
|
|
* Get a byte from the dictionary at the given distance. The distance is
|
|
* assumed to valid, or as a special case, zero when the dictionary is
|
|
* still empty. This special case is needed for single-call decoding to
|
|
* avoid writing a '\0' to the end of the destination buffer.
|
|
*/
|
|
static inline uint32_t dict_get(const struct dictionary *dict, uint32_t dist)
|
|
{
|
|
size_t offset = dict->pos - dist - 1;
|
|
|
|
if (dist >= dict->pos)
|
|
offset += dict->end;
|
|
|
|
return dict->full > 0 ? dict->buf[offset] : 0;
|
|
}
|
|
|
|
/*
|
|
* Put one byte into the dictionary. It is assumed that there is space for it.
|
|
*/
|
|
static inline void dict_put(struct dictionary *dict, uint8_t byte)
|
|
{
|
|
dict->buf[dict->pos++] = byte;
|
|
|
|
if (dict->full < dict->pos)
|
|
dict->full = dict->pos;
|
|
}
|
|
|
|
/*
|
|
* Repeat given number of bytes from the given distance. If the distance is
|
|
* invalid, false is returned. On success, true is returned and *len is
|
|
* updated to indicate how many bytes were left to be repeated.
|
|
*/
|
|
static bool dict_repeat(struct dictionary *dict, uint32_t *len, uint32_t dist)
|
|
{
|
|
size_t back;
|
|
uint32_t left;
|
|
|
|
if (dist >= dict->full || dist >= dict->size)
|
|
return false;
|
|
|
|
left = min_t(size_t, dict->limit - dict->pos, *len);
|
|
*len -= left;
|
|
|
|
back = dict->pos - dist - 1;
|
|
if (dist >= dict->pos)
|
|
back += dict->end;
|
|
|
|
do {
|
|
dict->buf[dict->pos++] = dict->buf[back++];
|
|
if (back == dict->end)
|
|
back = 0;
|
|
} while (--left > 0);
|
|
|
|
if (dict->full < dict->pos)
|
|
dict->full = dict->pos;
|
|
|
|
return true;
|
|
}
|
|
|
|
/* Copy uncompressed data as is from input to dictionary and output buffers. */
|
|
static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
|
|
uint32_t *left)
|
|
{
|
|
size_t copy_size;
|
|
|
|
while (*left > 0 && b->in_pos < b->in_size
|
|
&& b->out_pos < b->out_size) {
|
|
copy_size = min(b->in_size - b->in_pos,
|
|
b->out_size - b->out_pos);
|
|
if (copy_size > dict->end - dict->pos)
|
|
copy_size = dict->end - dict->pos;
|
|
if (copy_size > *left)
|
|
copy_size = *left;
|
|
|
|
*left -= copy_size;
|
|
|
|
/*
|
|
* If doing in-place decompression in single-call mode and the
|
|
* uncompressed size of the file is larger than the caller
|
|
* thought (i.e. it is invalid input!), the buffers below may
|
|
* overlap and cause undefined behavior with memcpy().
|
|
* With valid inputs memcpy() would be fine here.
|
|
*/
|
|
memmove(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
|
|
dict->pos += copy_size;
|
|
|
|
if (dict->full < dict->pos)
|
|
dict->full = dict->pos;
|
|
|
|
if (DEC_IS_MULTI(dict->mode)) {
|
|
if (dict->pos == dict->end)
|
|
dict->pos = 0;
|
|
|
|
/*
|
|
* Like above but for multi-call mode: use memmove()
|
|
* to avoid undefined behavior with invalid input.
|
|
*/
|
|
memmove(b->out + b->out_pos, b->in + b->in_pos,
|
|
copy_size);
|
|
}
|
|
|
|
dict->start = dict->pos;
|
|
|
|
b->out_pos += copy_size;
|
|
b->in_pos += copy_size;
|
|
}
|
|
}
|
|
|
|
#ifdef XZ_DEC_MICROLZMA
|
|
# define DICT_FLUSH_SUPPORTS_SKIPPING true
|
|
#else
|
|
# define DICT_FLUSH_SUPPORTS_SKIPPING false
|
|
#endif
|
|
|
|
/*
|
|
* Flush pending data from dictionary to b->out. It is assumed that there is
|
|
* enough space in b->out. This is guaranteed because caller uses dict_limit()
|
|
* before decoding data into the dictionary.
|
|
*/
|
|
static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b)
|
|
{
|
|
size_t copy_size = dict->pos - dict->start;
|
|
|
|
if (DEC_IS_MULTI(dict->mode)) {
|
|
if (dict->pos == dict->end)
|
|
dict->pos = 0;
|
|
|
|
/*
|
|
* These buffers cannot overlap even if doing in-place
|
|
* decompression because in multi-call mode dict->buf
|
|
* has been allocated by us in this file; it's not
|
|
* provided by the caller like in single-call mode.
|
|
*
|
|
* With MicroLZMA, b->out can be NULL to skip bytes that
|
|
* the caller doesn't need. This cannot be done with XZ
|
|
* because it would break BCJ filters.
|
|
*/
|
|
if (!DICT_FLUSH_SUPPORTS_SKIPPING || b->out != NULL)
|
|
memcpy(b->out + b->out_pos, dict->buf + dict->start,
|
|
copy_size);
|
|
}
|
|
|
|
dict->start = dict->pos;
|
|
b->out_pos += copy_size;
|
|
return copy_size;
|
|
}
|
|
|
|
/*****************
|
|
* Range decoder *
|
|
*****************/
|
|
|
|
/* Reset the range decoder. */
|
|
static void rc_reset(struct rc_dec *rc)
|
|
{
|
|
rc->range = (uint32_t)-1;
|
|
rc->code = 0;
|
|
rc->init_bytes_left = RC_INIT_BYTES;
|
|
}
|
|
|
|
/*
|
|
* Read the first five initial bytes into rc->code if they haven't been
|
|
* read already. (Yes, the first byte gets completely ignored.)
|
|
*/
|
|
static bool rc_read_init(struct rc_dec *rc, struct xz_buf *b)
|
|
{
|
|
while (rc->init_bytes_left > 0) {
|
|
if (b->in_pos == b->in_size)
|
|
return false;
|
|
|
|
rc->code = (rc->code << 8) + b->in[b->in_pos++];
|
|
--rc->init_bytes_left;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/* Return true if there may not be enough input for the next decoding loop. */
|
|
static inline bool rc_limit_exceeded(const struct rc_dec *rc)
|
|
{
|
|
return rc->in_pos > rc->in_limit;
|
|
}
|
|
|
|
/*
|
|
* Return true if it is possible (from point of view of range decoder) that
|
|
* we have reached the end of the LZMA chunk.
|
|
*/
|
|
static inline bool rc_is_finished(const struct rc_dec *rc)
|
|
{
|
|
return rc->code == 0;
|
|
}
|
|
|
|
/* Read the next input byte if needed. */
|
|
static __always_inline void rc_normalize(struct rc_dec *rc)
|
|
{
|
|
if (rc->range < RC_TOP_VALUE) {
|
|
rc->range <<= RC_SHIFT_BITS;
|
|
rc->code = (rc->code << RC_SHIFT_BITS) + rc->in[rc->in_pos++];
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Decode one bit. In some versions, this function has been split in three
|
|
* functions so that the compiler is supposed to be able to more easily avoid
|
|
* an extra branch. In this particular version of the LZMA decoder, this
|
|
* doesn't seem to be a good idea (tested with GCC 3.3.6, 3.4.6, and 4.3.3
|
|
* on x86). Using a non-splitted version results in nicer looking code too.
|
|
*
|
|
* NOTE: This must return an int. Do not make it return a bool or the speed
|
|
* of the code generated by GCC 3.x decreases 10-15 %. (GCC 4.3 doesn't care,
|
|
* and it generates 10-20 % faster code than GCC 3.x from this file anyway.)
|
|
*/
|
|
static __always_inline int rc_bit(struct rc_dec *rc, uint16_t *prob)
|
|
{
|
|
uint32_t bound;
|
|
int bit;
|
|
|
|
rc_normalize(rc);
|
|
bound = (rc->range >> RC_BIT_MODEL_TOTAL_BITS) * *prob;
|
|
if (rc->code < bound) {
|
|
rc->range = bound;
|
|
*prob += (RC_BIT_MODEL_TOTAL - *prob) >> RC_MOVE_BITS;
|
|
bit = 0;
|
|
} else {
|
|
rc->range -= bound;
|
|
rc->code -= bound;
|
|
*prob -= *prob >> RC_MOVE_BITS;
|
|
bit = 1;
|
|
}
|
|
|
|
return bit;
|
|
}
|
|
|
|
/* Decode a bittree starting from the most significant bit. */
|
|
static __always_inline uint32_t rc_bittree(struct rc_dec *rc,
|
|
uint16_t *probs, uint32_t limit)
|
|
{
|
|
uint32_t symbol = 1;
|
|
|
|
do {
|
|
if (rc_bit(rc, &probs[symbol]))
|
|
symbol = (symbol << 1) + 1;
|
|
else
|
|
symbol <<= 1;
|
|
} while (symbol < limit);
|
|
|
|
return symbol;
|
|
}
|
|
|
|
/* Decode a bittree starting from the least significant bit. */
|
|
static __always_inline void rc_bittree_reverse(struct rc_dec *rc,
|
|
uint16_t *probs,
|
|
uint32_t *dest, uint32_t limit)
|
|
{
|
|
uint32_t symbol = 1;
|
|
uint32_t i = 0;
|
|
|
|
do {
|
|
if (rc_bit(rc, &probs[symbol])) {
|
|
symbol = (symbol << 1) + 1;
|
|
*dest += 1 << i;
|
|
} else {
|
|
symbol <<= 1;
|
|
}
|
|
} while (++i < limit);
|
|
}
|
|
|
|
/* Decode direct bits (fixed fifty-fifty probability) */
|
|
static inline void rc_direct(struct rc_dec *rc, uint32_t *dest, uint32_t limit)
|
|
{
|
|
uint32_t mask;
|
|
|
|
do {
|
|
rc_normalize(rc);
|
|
rc->range >>= 1;
|
|
rc->code -= rc->range;
|
|
mask = (uint32_t)0 - (rc->code >> 31);
|
|
rc->code += rc->range & mask;
|
|
*dest = (*dest << 1) + (mask + 1);
|
|
} while (--limit > 0);
|
|
}
|
|
|
|
/********
|
|
* LZMA *
|
|
********/
|
|
|
|
/* Get pointer to literal coder probability array. */
|
|
static uint16_t *lzma_literal_probs(struct xz_dec_lzma2 *s)
|
|
{
|
|
uint32_t prev_byte = dict_get(&s->dict, 0);
|
|
uint32_t low = prev_byte >> (8 - s->lzma.lc);
|
|
uint32_t high = (s->dict.pos & s->lzma.literal_pos_mask) << s->lzma.lc;
|
|
return s->lzma.literal[low + high];
|
|
}
|
|
|
|
/* Decode a literal (one 8-bit byte) */
|
|
static void lzma_literal(struct xz_dec_lzma2 *s)
|
|
{
|
|
uint16_t *probs;
|
|
uint32_t symbol;
|
|
uint32_t match_byte;
|
|
uint32_t match_bit;
|
|
uint32_t offset;
|
|
uint32_t i;
|
|
|
|
probs = lzma_literal_probs(s);
|
|
|
|
if (lzma_state_is_literal(s->lzma.state)) {
|
|
symbol = rc_bittree(&s->rc, probs, 0x100);
|
|
} else {
|
|
symbol = 1;
|
|
match_byte = dict_get(&s->dict, s->lzma.rep0) << 1;
|
|
offset = 0x100;
|
|
|
|
do {
|
|
match_bit = match_byte & offset;
|
|
match_byte <<= 1;
|
|
i = offset + match_bit + symbol;
|
|
|
|
if (rc_bit(&s->rc, &probs[i])) {
|
|
symbol = (symbol << 1) + 1;
|
|
offset &= match_bit;
|
|
} else {
|
|
symbol <<= 1;
|
|
offset &= ~match_bit;
|
|
}
|
|
} while (symbol < 0x100);
|
|
}
|
|
|
|
dict_put(&s->dict, (uint8_t)symbol);
|
|
lzma_state_literal(&s->lzma.state);
|
|
}
|
|
|
|
/* Decode the length of the match into s->lzma.len. */
|
|
static void lzma_len(struct xz_dec_lzma2 *s, struct lzma_len_dec *l,
|
|
uint32_t pos_state)
|
|
{
|
|
uint16_t *probs;
|
|
uint32_t limit;
|
|
|
|
if (!rc_bit(&s->rc, &l->choice)) {
|
|
probs = l->low[pos_state];
|
|
limit = LEN_LOW_SYMBOLS;
|
|
s->lzma.len = MATCH_LEN_MIN;
|
|
} else {
|
|
if (!rc_bit(&s->rc, &l->choice2)) {
|
|
probs = l->mid[pos_state];
|
|
limit = LEN_MID_SYMBOLS;
|
|
s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS;
|
|
} else {
|
|
probs = l->high;
|
|
limit = LEN_HIGH_SYMBOLS;
|
|
s->lzma.len = MATCH_LEN_MIN + LEN_LOW_SYMBOLS
|
|
+ LEN_MID_SYMBOLS;
|
|
}
|
|
}
|
|
|
|
s->lzma.len += rc_bittree(&s->rc, probs, limit) - limit;
|
|
}
|
|
|
|
/* Decode a match. The distance will be stored in s->lzma.rep0. */
|
|
static void lzma_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
|
|
{
|
|
uint16_t *probs;
|
|
uint32_t dist_slot;
|
|
uint32_t limit;
|
|
|
|
lzma_state_match(&s->lzma.state);
|
|
|
|
s->lzma.rep3 = s->lzma.rep2;
|
|
s->lzma.rep2 = s->lzma.rep1;
|
|
s->lzma.rep1 = s->lzma.rep0;
|
|
|
|
lzma_len(s, &s->lzma.match_len_dec, pos_state);
|
|
|
|
probs = s->lzma.dist_slot[lzma_get_dist_state(s->lzma.len)];
|
|
dist_slot = rc_bittree(&s->rc, probs, DIST_SLOTS) - DIST_SLOTS;
|
|
|
|
if (dist_slot < DIST_MODEL_START) {
|
|
s->lzma.rep0 = dist_slot;
|
|
} else {
|
|
limit = (dist_slot >> 1) - 1;
|
|
s->lzma.rep0 = 2 + (dist_slot & 1);
|
|
|
|
if (dist_slot < DIST_MODEL_END) {
|
|
s->lzma.rep0 <<= limit;
|
|
probs = s->lzma.dist_special + s->lzma.rep0
|
|
- dist_slot - 1;
|
|
rc_bittree_reverse(&s->rc, probs,
|
|
&s->lzma.rep0, limit);
|
|
} else {
|
|
rc_direct(&s->rc, &s->lzma.rep0, limit - ALIGN_BITS);
|
|
s->lzma.rep0 <<= ALIGN_BITS;
|
|
rc_bittree_reverse(&s->rc, s->lzma.dist_align,
|
|
&s->lzma.rep0, ALIGN_BITS);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Decode a repeated match. The distance is one of the four most recently
|
|
* seen matches. The distance will be stored in s->lzma.rep0.
|
|
*/
|
|
static void lzma_rep_match(struct xz_dec_lzma2 *s, uint32_t pos_state)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
if (!rc_bit(&s->rc, &s->lzma.is_rep0[s->lzma.state])) {
|
|
if (!rc_bit(&s->rc, &s->lzma.is_rep0_long[
|
|
s->lzma.state][pos_state])) {
|
|
lzma_state_short_rep(&s->lzma.state);
|
|
s->lzma.len = 1;
|
|
return;
|
|
}
|
|
} else {
|
|
if (!rc_bit(&s->rc, &s->lzma.is_rep1[s->lzma.state])) {
|
|
tmp = s->lzma.rep1;
|
|
} else {
|
|
if (!rc_bit(&s->rc, &s->lzma.is_rep2[s->lzma.state])) {
|
|
tmp = s->lzma.rep2;
|
|
} else {
|
|
tmp = s->lzma.rep3;
|
|
s->lzma.rep3 = s->lzma.rep2;
|
|
}
|
|
|
|
s->lzma.rep2 = s->lzma.rep1;
|
|
}
|
|
|
|
s->lzma.rep1 = s->lzma.rep0;
|
|
s->lzma.rep0 = tmp;
|
|
}
|
|
|
|
lzma_state_long_rep(&s->lzma.state);
|
|
lzma_len(s, &s->lzma.rep_len_dec, pos_state);
|
|
}
|
|
|
|
/* LZMA decoder core */
|
|
static bool lzma_main(struct xz_dec_lzma2 *s)
|
|
{
|
|
uint32_t pos_state;
|
|
|
|
/*
|
|
* If the dictionary was reached during the previous call, try to
|
|
* finish the possibly pending repeat in the dictionary.
|
|
*/
|
|
if (dict_has_space(&s->dict) && s->lzma.len > 0)
|
|
dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0);
|
|
|
|
/*
|
|
* Decode more LZMA symbols. One iteration may consume up to
|
|
* LZMA_IN_REQUIRED - 1 bytes.
|
|
*/
|
|
while (dict_has_space(&s->dict) && !rc_limit_exceeded(&s->rc)) {
|
|
pos_state = s->dict.pos & s->lzma.pos_mask;
|
|
|
|
if (!rc_bit(&s->rc, &s->lzma.is_match[
|
|
s->lzma.state][pos_state])) {
|
|
lzma_literal(s);
|
|
} else {
|
|
if (rc_bit(&s->rc, &s->lzma.is_rep[s->lzma.state]))
|
|
lzma_rep_match(s, pos_state);
|
|
else
|
|
lzma_match(s, pos_state);
|
|
|
|
if (!dict_repeat(&s->dict, &s->lzma.len, s->lzma.rep0))
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Having the range decoder always normalized when we are outside
|
|
* this function makes it easier to correctly handle end of the chunk.
|
|
*/
|
|
rc_normalize(&s->rc);
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Reset the LZMA decoder and range decoder state. Dictionary is not reset
|
|
* here, because LZMA state may be reset without resetting the dictionary.
|
|
*/
|
|
static void lzma_reset(struct xz_dec_lzma2 *s)
|
|
{
|
|
uint16_t *probs;
|
|
size_t i;
|
|
|
|
s->lzma.state = STATE_LIT_LIT;
|
|
s->lzma.rep0 = 0;
|
|
s->lzma.rep1 = 0;
|
|
s->lzma.rep2 = 0;
|
|
s->lzma.rep3 = 0;
|
|
s->lzma.len = 0;
|
|
|
|
/*
|
|
* All probabilities are initialized to the same value. This hack
|
|
* makes the code smaller by avoiding a separate loop for each
|
|
* probability array.
|
|
*
|
|
* This could be optimized so that only that part of literal
|
|
* probabilities that are actually required. In the common case
|
|
* we would write 12 KiB less.
|
|
*/
|
|
probs = s->lzma.is_match[0];
|
|
for (i = 0; i < PROBS_TOTAL; ++i)
|
|
probs[i] = RC_BIT_MODEL_TOTAL / 2;
|
|
|
|
rc_reset(&s->rc);
|
|
}
|
|
|
|
/*
|
|
* Decode and validate LZMA properties (lc/lp/pb) and calculate the bit masks
|
|
* from the decoded lp and pb values. On success, the LZMA decoder state is
|
|
* reset and true is returned.
|
|
*/
|
|
static bool lzma_props(struct xz_dec_lzma2 *s, uint8_t props)
|
|
{
|
|
if (props > (4 * 5 + 4) * 9 + 8)
|
|
return false;
|
|
|
|
s->lzma.pos_mask = 0;
|
|
while (props >= 9 * 5) {
|
|
props -= 9 * 5;
|
|
++s->lzma.pos_mask;
|
|
}
|
|
|
|
s->lzma.pos_mask = (1 << s->lzma.pos_mask) - 1;
|
|
|
|
s->lzma.literal_pos_mask = 0;
|
|
while (props >= 9) {
|
|
props -= 9;
|
|
++s->lzma.literal_pos_mask;
|
|
}
|
|
|
|
s->lzma.lc = props;
|
|
|
|
if (s->lzma.lc + s->lzma.literal_pos_mask > 4)
|
|
return false;
|
|
|
|
s->lzma.literal_pos_mask = (1 << s->lzma.literal_pos_mask) - 1;
|
|
|
|
lzma_reset(s);
|
|
|
|
return true;
|
|
}
|
|
|
|
/*********
|
|
* LZMA2 *
|
|
*********/
|
|
|
|
/*
|
|
* The LZMA decoder assumes that if the input limit (s->rc.in_limit) hasn't
|
|
* been exceeded, it is safe to read up to LZMA_IN_REQUIRED bytes. This
|
|
* wrapper function takes care of making the LZMA decoder's assumption safe.
|
|
*
|
|
* As long as there is plenty of input left to be decoded in the current LZMA
|
|
* chunk, we decode directly from the caller-supplied input buffer until
|
|
* there's LZMA_IN_REQUIRED bytes left. Those remaining bytes are copied into
|
|
* s->temp.buf, which (hopefully) gets filled on the next call to this
|
|
* function. We decode a few bytes from the temporary buffer so that we can
|
|
* continue decoding from the caller-supplied input buffer again.
|
|
*/
|
|
static bool lzma2_lzma(struct xz_dec_lzma2 *s, struct xz_buf *b)
|
|
{
|
|
size_t in_avail;
|
|
uint32_t tmp;
|
|
|
|
in_avail = b->in_size - b->in_pos;
|
|
if (s->temp.size > 0 || s->lzma2.compressed == 0) {
|
|
tmp = 2 * LZMA_IN_REQUIRED - s->temp.size;
|
|
if (tmp > s->lzma2.compressed - s->temp.size)
|
|
tmp = s->lzma2.compressed - s->temp.size;
|
|
if (tmp > in_avail)
|
|
tmp = in_avail;
|
|
|
|
memcpy(s->temp.buf + s->temp.size, b->in + b->in_pos, tmp);
|
|
|
|
if (s->temp.size + tmp == s->lzma2.compressed) {
|
|
memzero(s->temp.buf + s->temp.size + tmp,
|
|
sizeof(s->temp.buf)
|
|
- s->temp.size - tmp);
|
|
s->rc.in_limit = s->temp.size + tmp;
|
|
} else if (s->temp.size + tmp < LZMA_IN_REQUIRED) {
|
|
s->temp.size += tmp;
|
|
b->in_pos += tmp;
|
|
return true;
|
|
} else {
|
|
s->rc.in_limit = s->temp.size + tmp - LZMA_IN_REQUIRED;
|
|
}
|
|
|
|
s->rc.in = s->temp.buf;
|
|
s->rc.in_pos = 0;
|
|
|
|
if (!lzma_main(s) || s->rc.in_pos > s->temp.size + tmp)
|
|
return false;
|
|
|
|
s->lzma2.compressed -= s->rc.in_pos;
|
|
|
|
if (s->rc.in_pos < s->temp.size) {
|
|
s->temp.size -= s->rc.in_pos;
|
|
memmove(s->temp.buf, s->temp.buf + s->rc.in_pos,
|
|
s->temp.size);
|
|
return true;
|
|
}
|
|
|
|
b->in_pos += s->rc.in_pos - s->temp.size;
|
|
s->temp.size = 0;
|
|
}
|
|
|
|
in_avail = b->in_size - b->in_pos;
|
|
if (in_avail >= LZMA_IN_REQUIRED) {
|
|
s->rc.in = b->in;
|
|
s->rc.in_pos = b->in_pos;
|
|
|
|
if (in_avail >= s->lzma2.compressed + LZMA_IN_REQUIRED)
|
|
s->rc.in_limit = b->in_pos + s->lzma2.compressed;
|
|
else
|
|
s->rc.in_limit = b->in_size - LZMA_IN_REQUIRED;
|
|
|
|
if (!lzma_main(s))
|
|
return false;
|
|
|
|
in_avail = s->rc.in_pos - b->in_pos;
|
|
if (in_avail > s->lzma2.compressed)
|
|
return false;
|
|
|
|
s->lzma2.compressed -= in_avail;
|
|
b->in_pos = s->rc.in_pos;
|
|
}
|
|
|
|
in_avail = b->in_size - b->in_pos;
|
|
if (in_avail < LZMA_IN_REQUIRED) {
|
|
if (in_avail > s->lzma2.compressed)
|
|
in_avail = s->lzma2.compressed;
|
|
|
|
memcpy(s->temp.buf, b->in + b->in_pos, in_avail);
|
|
s->temp.size = in_avail;
|
|
b->in_pos += in_avail;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/*
|
|
* Take care of the LZMA2 control layer, and forward the job of actual LZMA
|
|
* decoding or copying of uncompressed chunks to other functions.
|
|
*/
|
|
XZ_EXTERN enum xz_ret xz_dec_lzma2_run(struct xz_dec_lzma2 *s,
|
|
struct xz_buf *b)
|
|
{
|
|
uint32_t tmp;
|
|
|
|
while (b->in_pos < b->in_size || s->lzma2.sequence == SEQ_LZMA_RUN) {
|
|
switch (s->lzma2.sequence) {
|
|
case SEQ_CONTROL:
|
|
/*
|
|
* LZMA2 control byte
|
|
*
|
|
* Exact values:
|
|
* 0x00 End marker
|
|
* 0x01 Dictionary reset followed by
|
|
* an uncompressed chunk
|
|
* 0x02 Uncompressed chunk (no dictionary reset)
|
|
*
|
|
* Highest three bits (s->control & 0xE0):
|
|
* 0xE0 Dictionary reset, new properties and state
|
|
* reset, followed by LZMA compressed chunk
|
|
* 0xC0 New properties and state reset, followed
|
|
* by LZMA compressed chunk (no dictionary
|
|
* reset)
|
|
* 0xA0 State reset using old properties,
|
|
* followed by LZMA compressed chunk (no
|
|
* dictionary reset)
|
|
* 0x80 LZMA chunk (no dictionary or state reset)
|
|
*
|
|
* For LZMA compressed chunks, the lowest five bits
|
|
* (s->control & 1F) are the highest bits of the
|
|
* uncompressed size (bits 16-20).
|
|
*
|
|
* A new LZMA2 stream must begin with a dictionary
|
|
* reset. The first LZMA chunk must set new
|
|
* properties and reset the LZMA state.
|
|
*
|
|
* Values that don't match anything described above
|
|
* are invalid and we return XZ_DATA_ERROR.
|
|
*/
|
|
tmp = b->in[b->in_pos++];
|
|
|
|
if (tmp == 0x00)
|
|
return XZ_STREAM_END;
|
|
|
|
if (tmp >= 0xE0 || tmp == 0x01) {
|
|
s->lzma2.need_props = true;
|
|
s->lzma2.need_dict_reset = false;
|
|
dict_reset(&s->dict, b);
|
|
} else if (s->lzma2.need_dict_reset) {
|
|
return XZ_DATA_ERROR;
|
|
}
|
|
|
|
if (tmp >= 0x80) {
|
|
s->lzma2.uncompressed = (tmp & 0x1F) << 16;
|
|
s->lzma2.sequence = SEQ_UNCOMPRESSED_1;
|
|
|
|
if (tmp >= 0xC0) {
|
|
/*
|
|
* When there are new properties,
|
|
* state reset is done at
|
|
* SEQ_PROPERTIES.
|
|
*/
|
|
s->lzma2.need_props = false;
|
|
s->lzma2.next_sequence
|
|
= SEQ_PROPERTIES;
|
|
|
|
} else if (s->lzma2.need_props) {
|
|
return XZ_DATA_ERROR;
|
|
|
|
} else {
|
|
s->lzma2.next_sequence
|
|
= SEQ_LZMA_PREPARE;
|
|
if (tmp >= 0xA0)
|
|
lzma_reset(s);
|
|
}
|
|
} else {
|
|
if (tmp > 0x02)
|
|
return XZ_DATA_ERROR;
|
|
|
|
s->lzma2.sequence = SEQ_COMPRESSED_0;
|
|
s->lzma2.next_sequence = SEQ_COPY;
|
|
}
|
|
|
|
break;
|
|
|
|
case SEQ_UNCOMPRESSED_1:
|
|
s->lzma2.uncompressed
|
|
+= (uint32_t)b->in[b->in_pos++] << 8;
|
|
s->lzma2.sequence = SEQ_UNCOMPRESSED_2;
|
|
break;
|
|
|
|
case SEQ_UNCOMPRESSED_2:
|
|
s->lzma2.uncompressed
|
|
+= (uint32_t)b->in[b->in_pos++] + 1;
|
|
s->lzma2.sequence = SEQ_COMPRESSED_0;
|
|
break;
|
|
|
|
case SEQ_COMPRESSED_0:
|
|
s->lzma2.compressed
|
|
= (uint32_t)b->in[b->in_pos++] << 8;
|
|
s->lzma2.sequence = SEQ_COMPRESSED_1;
|
|
break;
|
|
|
|
case SEQ_COMPRESSED_1:
|
|
s->lzma2.compressed
|
|
+= (uint32_t)b->in[b->in_pos++] + 1;
|
|
s->lzma2.sequence = s->lzma2.next_sequence;
|
|
break;
|
|
|
|
case SEQ_PROPERTIES:
|
|
if (!lzma_props(s, b->in[b->in_pos++]))
|
|
return XZ_DATA_ERROR;
|
|
|
|
s->lzma2.sequence = SEQ_LZMA_PREPARE;
|
|
|
|
fallthrough;
|
|
|
|
case SEQ_LZMA_PREPARE:
|
|
if (s->lzma2.compressed < RC_INIT_BYTES)
|
|
return XZ_DATA_ERROR;
|
|
|
|
if (!rc_read_init(&s->rc, b))
|
|
return XZ_OK;
|
|
|
|
s->lzma2.compressed -= RC_INIT_BYTES;
|
|
s->lzma2.sequence = SEQ_LZMA_RUN;
|
|
|
|
fallthrough;
|
|
|
|
case SEQ_LZMA_RUN:
|
|
/*
|
|
* Set dictionary limit to indicate how much we want
|
|
* to be encoded at maximum. Decode new data into the
|
|
* dictionary. Flush the new data from dictionary to
|
|
* b->out. Check if we finished decoding this chunk.
|
|
* In case the dictionary got full but we didn't fill
|
|
* the output buffer yet, we may run this loop
|
|
* multiple times without changing s->lzma2.sequence.
|
|
*/
|
|
dict_limit(&s->dict, min_t(size_t,
|
|
b->out_size - b->out_pos,
|
|
s->lzma2.uncompressed));
|
|
if (!lzma2_lzma(s, b))
|
|
return XZ_DATA_ERROR;
|
|
|
|
s->lzma2.uncompressed -= dict_flush(&s->dict, b);
|
|
|
|
if (s->lzma2.uncompressed == 0) {
|
|
if (s->lzma2.compressed > 0 || s->lzma.len > 0
|
|
|| !rc_is_finished(&s->rc))
|
|
return XZ_DATA_ERROR;
|
|
|
|
rc_reset(&s->rc);
|
|
s->lzma2.sequence = SEQ_CONTROL;
|
|
|
|
} else if (b->out_pos == b->out_size
|
|
|| (b->in_pos == b->in_size
|
|
&& s->temp.size
|
|
< s->lzma2.compressed)) {
|
|
return XZ_OK;
|
|
}
|
|
|
|
break;
|
|
|
|
case SEQ_COPY:
|
|
dict_uncompressed(&s->dict, b, &s->lzma2.compressed);
|
|
if (s->lzma2.compressed > 0)
|
|
return XZ_OK;
|
|
|
|
s->lzma2.sequence = SEQ_CONTROL;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return XZ_OK;
|
|
}
|
|
|
|
XZ_EXTERN struct xz_dec_lzma2 *xz_dec_lzma2_create(enum xz_mode mode,
|
|
uint32_t dict_max)
|
|
{
|
|
struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL);
|
|
if (s == NULL)
|
|
return NULL;
|
|
|
|
s->dict.mode = mode;
|
|
s->dict.size_max = dict_max;
|
|
|
|
if (DEC_IS_PREALLOC(mode)) {
|
|
s->dict.buf = vmalloc(dict_max);
|
|
if (s->dict.buf == NULL) {
|
|
kfree(s);
|
|
return NULL;
|
|
}
|
|
} else if (DEC_IS_DYNALLOC(mode)) {
|
|
s->dict.buf = NULL;
|
|
s->dict.allocated = 0;
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, uint8_t props)
|
|
{
|
|
/* This limits dictionary size to 3 GiB to keep parsing simpler. */
|
|
if (props > 39)
|
|
return XZ_OPTIONS_ERROR;
|
|
|
|
s->dict.size = 2 + (props & 1);
|
|
s->dict.size <<= (props >> 1) + 11;
|
|
|
|
if (DEC_IS_MULTI(s->dict.mode)) {
|
|
if (s->dict.size > s->dict.size_max)
|
|
return XZ_MEMLIMIT_ERROR;
|
|
|
|
s->dict.end = s->dict.size;
|
|
|
|
if (DEC_IS_DYNALLOC(s->dict.mode)) {
|
|
if (s->dict.allocated < s->dict.size) {
|
|
s->dict.allocated = s->dict.size;
|
|
vfree(s->dict.buf);
|
|
s->dict.buf = vmalloc(s->dict.size);
|
|
if (s->dict.buf == NULL) {
|
|
s->dict.allocated = 0;
|
|
return XZ_MEM_ERROR;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
s->lzma2.sequence = SEQ_CONTROL;
|
|
s->lzma2.need_dict_reset = true;
|
|
|
|
s->temp.size = 0;
|
|
|
|
return XZ_OK;
|
|
}
|
|
|
|
XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s)
|
|
{
|
|
if (DEC_IS_MULTI(s->dict.mode))
|
|
vfree(s->dict.buf);
|
|
|
|
kfree(s);
|
|
}
|
|
|
|
#ifdef XZ_DEC_MICROLZMA
|
|
/* This is a wrapper struct to have a nice struct name in the public API. */
|
|
struct xz_dec_microlzma {
|
|
struct xz_dec_lzma2 s;
|
|
};
|
|
|
|
enum xz_ret xz_dec_microlzma_run(struct xz_dec_microlzma *s_ptr,
|
|
struct xz_buf *b)
|
|
{
|
|
struct xz_dec_lzma2 *s = &s_ptr->s;
|
|
|
|
/*
|
|
* sequence is SEQ_PROPERTIES before the first input byte,
|
|
* SEQ_LZMA_PREPARE until a total of five bytes have been read,
|
|
* and SEQ_LZMA_RUN for the rest of the input stream.
|
|
*/
|
|
if (s->lzma2.sequence != SEQ_LZMA_RUN) {
|
|
if (s->lzma2.sequence == SEQ_PROPERTIES) {
|
|
/* One byte is needed for the props. */
|
|
if (b->in_pos >= b->in_size)
|
|
return XZ_OK;
|
|
|
|
/*
|
|
* Don't increment b->in_pos here. The same byte is
|
|
* also passed to rc_read_init() which will ignore it.
|
|
*/
|
|
if (!lzma_props(s, ~b->in[b->in_pos]))
|
|
return XZ_DATA_ERROR;
|
|
|
|
s->lzma2.sequence = SEQ_LZMA_PREPARE;
|
|
}
|
|
|
|
/*
|
|
* xz_dec_microlzma_reset() doesn't validate the compressed
|
|
* size so we do it here. We have to limit the maximum size
|
|
* to avoid integer overflows in lzma2_lzma(). 3 GiB is a nice
|
|
* round number and much more than users of this code should
|
|
* ever need.
|
|
*/
|
|
if (s->lzma2.compressed < RC_INIT_BYTES
|
|
|| s->lzma2.compressed > (3U << 30))
|
|
return XZ_DATA_ERROR;
|
|
|
|
if (!rc_read_init(&s->rc, b))
|
|
return XZ_OK;
|
|
|
|
s->lzma2.compressed -= RC_INIT_BYTES;
|
|
s->lzma2.sequence = SEQ_LZMA_RUN;
|
|
|
|
dict_reset(&s->dict, b);
|
|
}
|
|
|
|
/* This is to allow increasing b->out_size between calls. */
|
|
if (DEC_IS_SINGLE(s->dict.mode))
|
|
s->dict.end = b->out_size - b->out_pos;
|
|
|
|
while (true) {
|
|
dict_limit(&s->dict, min_t(size_t, b->out_size - b->out_pos,
|
|
s->lzma2.uncompressed));
|
|
|
|
if (!lzma2_lzma(s, b))
|
|
return XZ_DATA_ERROR;
|
|
|
|
s->lzma2.uncompressed -= dict_flush(&s->dict, b);
|
|
|
|
if (s->lzma2.uncompressed == 0) {
|
|
if (s->lzma2.pedantic_microlzma) {
|
|
if (s->lzma2.compressed > 0 || s->lzma.len > 0
|
|
|| !rc_is_finished(&s->rc))
|
|
return XZ_DATA_ERROR;
|
|
}
|
|
|
|
return XZ_STREAM_END;
|
|
}
|
|
|
|
if (b->out_pos == b->out_size)
|
|
return XZ_OK;
|
|
|
|
if (b->in_pos == b->in_size
|
|
&& s->temp.size < s->lzma2.compressed)
|
|
return XZ_OK;
|
|
}
|
|
}
|
|
|
|
struct xz_dec_microlzma *xz_dec_microlzma_alloc(enum xz_mode mode,
|
|
uint32_t dict_size)
|
|
{
|
|
struct xz_dec_microlzma *s;
|
|
|
|
/* Restrict dict_size to the same range as in the LZMA2 code. */
|
|
if (dict_size < 4096 || dict_size > (3U << 30))
|
|
return NULL;
|
|
|
|
s = kmalloc(sizeof(*s), GFP_KERNEL);
|
|
if (s == NULL)
|
|
return NULL;
|
|
|
|
s->s.dict.mode = mode;
|
|
s->s.dict.size = dict_size;
|
|
|
|
if (DEC_IS_MULTI(mode)) {
|
|
s->s.dict.end = dict_size;
|
|
|
|
s->s.dict.buf = vmalloc(dict_size);
|
|
if (s->s.dict.buf == NULL) {
|
|
kfree(s);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return s;
|
|
}
|
|
|
|
void xz_dec_microlzma_reset(struct xz_dec_microlzma *s, uint32_t comp_size,
|
|
uint32_t uncomp_size, int uncomp_size_is_exact)
|
|
{
|
|
/*
|
|
* comp_size is validated in xz_dec_microlzma_run().
|
|
* uncomp_size can safely be anything.
|
|
*/
|
|
s->s.lzma2.compressed = comp_size;
|
|
s->s.lzma2.uncompressed = uncomp_size;
|
|
s->s.lzma2.pedantic_microlzma = uncomp_size_is_exact;
|
|
|
|
s->s.lzma2.sequence = SEQ_PROPERTIES;
|
|
s->s.temp.size = 0;
|
|
}
|
|
|
|
void xz_dec_microlzma_end(struct xz_dec_microlzma *s)
|
|
{
|
|
if (DEC_IS_MULTI(s->s.dict.mode))
|
|
vfree(s->s.dict.buf);
|
|
|
|
kfree(s);
|
|
}
|
|
#endif
|