aboutsummaryrefslogtreecommitdiff
path: root/linux/lib/xz/xz_dec_lzma2.c
diff options
context:
space:
mode:
Diffstat (limited to 'linux/lib/xz/xz_dec_lzma2.c')
-rw-r--r--linux/lib/xz/xz_dec_lzma2.c193
1 files changed, 12 insertions, 181 deletions
diff --git a/linux/lib/xz/xz_dec_lzma2.c b/linux/lib/xz/xz_dec_lzma2.c
index c929f1c..08c3c80 100644
--- a/linux/lib/xz/xz_dec_lzma2.c
+++ b/linux/lib/xz/xz_dec_lzma2.c
@@ -2,7 +2,7 @@
* LZMA2 decoder
*
* Authors: Lasse Collin <lasse.collin@tukaani.org>
- * Igor Pavlov <https://7-zip.org/>
+ * Igor Pavlov <http://7-zip.org/>
*
* This file has been put into the public domain.
* You can do whatever you want with this file.
@@ -147,8 +147,8 @@ struct lzma_dec {
/*
* 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
+ * context bits, a mask dervied from the number of literal
+ * position bits, and a mask dervied from the number
* position bits)
*/
uint32_t lc;
@@ -248,10 +248,6 @@ struct lzma2_dec {
* before the first LZMA chunk.
*/
bool need_props;
-
-#ifdef XZ_DEC_MICROLZMA
- bool pedantic_microlzma;
-#endif
};
struct xz_dec_lzma2 {
@@ -391,14 +387,7 @@ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
*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);
+ memcpy(dict->buf + dict->pos, b->in + b->in_pos, copy_size);
dict->pos += copy_size;
if (dict->full < dict->pos)
@@ -408,11 +397,7 @@ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
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,
+ memcpy(b->out + b->out_pos, b->in + b->in_pos,
copy_size);
}
@@ -423,12 +408,6 @@ static void dict_uncompressed(struct dictionary *dict, struct xz_buf *b,
}
}
-#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()
@@ -442,19 +421,8 @@ static uint32_t dict_flush(struct dictionary *dict, struct xz_buf *b)
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);
+ memcpy(b->out + b->out_pos, dict->buf + dict->start,
+ copy_size);
}
dict->start = dict->pos;
@@ -516,11 +484,11 @@ static __always_inline void rc_normalize(struct rc_dec *rc)
}
/*
- * Decode one bit. In some versions, this function has been split in three
+ * Decode one bit. In some versions, this function has been splitted 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-split version results in nicer looking code too.
+ * 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,
@@ -793,7 +761,7 @@ static bool lzma_main(struct xz_dec_lzma2 *s)
}
/*
- * Reset the LZMA decoder and range decoder state. Dictionary is not reset
+ * Reset the LZMA decoder and range decoder state. Dictionary is nore reset
* here, because LZMA state may be reset without resetting the dictionary.
*/
static void lzma_reset(struct xz_dec_lzma2 *s)
@@ -806,7 +774,6 @@ static void lzma_reset(struct xz_dec_lzma2 *s)
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
@@ -1179,7 +1146,6 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, uint8_t props)
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) {
@@ -1190,6 +1156,8 @@ XZ_EXTERN enum xz_ret xz_dec_lzma2_reset(struct xz_dec_lzma2 *s, uint8_t props)
}
}
+ s->lzma.len = 0;
+
s->lzma2.sequence = SEQ_CONTROL;
s->lzma2.need_dict_reset = true;
@@ -1205,140 +1173,3 @@ XZ_EXTERN void xz_dec_lzma2_end(struct xz_dec_lzma2 *s)
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