diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-20 02:40:56 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-20 02:40:56 +0200 |
commit | ba73cfd28464f9ef926dfd27e264215d4c4f8b1f (patch) | |
tree | 1388876b477579cb6f43b4eb12b258b61bc8f010 | |
parent | 91d7ee31f766a13595c1042d375f8374f2c3675f (diff) | |
download | busybox-w32-ba73cfd28464f9ef926dfd27e264215d4c4f8b1f.tar.gz busybox-w32-ba73cfd28464f9ef926dfd27e264215d4c4f8b1f.tar.bz2 busybox-w32-ba73cfd28464f9ef926dfd27e264215d4c4f8b1f.zip |
unxz: update from XZ embedded git
function old new delta
rc_reset - 21 +21
unpack_xz_stream 2342 2357 +15
lzma_reset 102 64 -38
lzma_len 506 443 -63
xz_dec_lzma2_run 1438 1374 -64
xz_dec_reset 73 - -73
lzma_main 2517 2183 -334
------------------------------------------------------------------------------
(add/remove: 1/1 grow/shrink: 1/4 up/down: 36/-572) Total: -536 bytes
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/libunarchive/decompress_unxz.c | 52 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz.h | 139 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_dec_lzma2.c | 200 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_dec_stream.c | 17 | ||||
-rw-r--r-- | archival/libunarchive/unxz/xz_private.h | 41 |
5 files changed, 270 insertions, 179 deletions
diff --git a/archival/libunarchive/decompress_unxz.c b/archival/libunarchive/decompress_unxz.c index 1302e29fb..800680fef 100644 --- a/archival/libunarchive/decompress_unxz.c +++ b/archival/libunarchive/decompress_unxz.c | |||
@@ -12,10 +12,11 @@ | |||
12 | #include "libbb.h" | 12 | #include "libbb.h" |
13 | #include "unarchive.h" | 13 | #include "unarchive.h" |
14 | 14 | ||
15 | #define XZ_REALLOC_DICT_BUF(ptr, size) xrealloc(ptr, size) | ||
16 | #define XZ_FUNC FAST_FUNC | 15 | #define XZ_FUNC FAST_FUNC |
17 | #define XZ_EXTERN static | 16 | #define XZ_EXTERN static |
18 | 17 | ||
18 | #define XZ_DEC_DYNALLOC | ||
19 | |||
19 | /* Skip check (rather than fail) of unsupported hash functions */ | 20 | /* Skip check (rather than fail) of unsupported hash functions */ |
20 | #define XZ_DEC_ANY_CHECK 1 | 21 | #define XZ_DEC_ANY_CHECK 1 |
21 | 22 | ||
@@ -40,15 +41,9 @@ static uint32_t xz_crc32(const uint8_t *buf, size_t size, uint32_t crc) | |||
40 | #define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val)) | 41 | #define put_unaligned_le32(val, buf) move_to_unaligned16(buf, SWAP_LE32(val)) |
41 | #define put_unaligned_be32(val, buf) move_to_unaligned16(buf, SWAP_BE32(val)) | 42 | #define put_unaligned_be32(val, buf) move_to_unaligned16(buf, SWAP_BE32(val)) |
42 | 43 | ||
43 | #include "unxz/xz.h" | ||
44 | #include "unxz/xz_config.h" | ||
45 | |||
46 | #include "unxz/xz_dec_bcj.c" | 44 | #include "unxz/xz_dec_bcj.c" |
47 | #include "unxz/xz_dec_lzma2.c" | 45 | #include "unxz/xz_dec_lzma2.c" |
48 | #include "unxz/xz_dec_stream.c" | 46 | #include "unxz/xz_dec_stream.c" |
49 | #include "unxz/xz_lzma2.h" | ||
50 | #include "unxz/xz_private.h" | ||
51 | #include "unxz/xz_stream.h" | ||
52 | 47 | ||
53 | IF_DESKTOP(long long) int FAST_FUNC | 48 | IF_DESKTOP(long long) int FAST_FUNC |
54 | unpack_xz_stream(int src_fd, int dst_fd) | 49 | unpack_xz_stream(int src_fd, int dst_fd) |
@@ -57,63 +52,50 @@ unpack_xz_stream(int src_fd, int dst_fd) | |||
57 | struct xz_dec *state; | 52 | struct xz_dec *state; |
58 | unsigned char *membuf; | 53 | unsigned char *membuf; |
59 | IF_DESKTOP(long long) int total = 0; | 54 | IF_DESKTOP(long long) int total = 0; |
60 | enum { | ||
61 | IN_SIZE = 4 * 1024, | ||
62 | OUT_SIZE = 60 * 1024, | ||
63 | }; | ||
64 | 55 | ||
65 | if (!crc32_table) | 56 | if (!crc32_table) |
66 | crc32_table = crc32_filltable(NULL, /*endian:*/ 0); | 57 | crc32_table = crc32_filltable(NULL, /*endian:*/ 0); |
67 | 58 | ||
68 | membuf = xmalloc(IN_SIZE + OUT_SIZE); | 59 | membuf = xmalloc(2 * BUFSIZ); |
69 | memset(&iobuf, 0, sizeof(iobuf)); | 60 | memset(&iobuf, 0, sizeof(iobuf)); |
70 | iobuf.in = membuf; | 61 | iobuf.in = membuf; |
71 | iobuf.out = membuf + IN_SIZE; | 62 | iobuf.out = membuf + BUFSIZ; |
72 | iobuf.out_size = OUT_SIZE; | 63 | iobuf.out_size = BUFSIZ; |
73 | 64 | ||
74 | state = xz_dec_init(64*1024); /* initial dict of 64k */ | 65 | /* Limit memory usage to about 64 MiB. */ |
66 | state = xz_dec_init(XZ_DYNALLOC, 64*1024*1024); | ||
75 | 67 | ||
76 | while (1) { | 68 | while (1) { |
77 | enum xz_ret r; | 69 | enum xz_ret r; |
78 | int insz, rd, outpos; | ||
79 | 70 | ||
80 | iobuf.in_size -= iobuf.in_pos; | 71 | if (iobuf.in_pos == iobuf.in_size) { |
81 | insz = iobuf.in_size; | 72 | int rd = safe_read(src_fd, membuf, BUFSIZ); |
82 | if (insz) | ||
83 | memmove(membuf, membuf + iobuf.in_pos, insz); | ||
84 | iobuf.in_pos = 0; | ||
85 | rd = IN_SIZE - insz; | ||
86 | if (rd) { | ||
87 | rd = safe_read(src_fd, membuf + insz, rd); | ||
88 | if (rd < 0) { | 73 | if (rd < 0) { |
89 | bb_error_msg(bb_msg_read_error); | 74 | bb_error_msg(bb_msg_read_error); |
90 | total = -1; | 75 | total = -1; |
91 | break; | 76 | break; |
92 | } | 77 | } |
93 | iobuf.in_size = insz + rd; | 78 | iobuf.in_size = rd; |
79 | iobuf.in_pos = 0; | ||
94 | } | 80 | } |
95 | // bb_error_msg(">in pos:%d size:%d out pos:%d size:%d", | 81 | // bb_error_msg(">in pos:%d size:%d out pos:%d size:%d", |
96 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size); | 82 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size); |
97 | r = xz_dec_run(state, &iobuf); | 83 | r = xz_dec_run(state, &iobuf); |
98 | // bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d", | 84 | // bb_error_msg("<in pos:%d size:%d out pos:%d size:%d r:%d", |
99 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r); | 85 | // iobuf.in_pos, iobuf.in_size, iobuf.out_pos, iobuf.out_size, r); |
100 | outpos = iobuf.out_pos; | 86 | if (iobuf.out_pos) { |
101 | if (outpos) { | 87 | xwrite(dst_fd, iobuf.out, iobuf.out_pos); |
102 | xwrite(dst_fd, iobuf.out, outpos); | 88 | IF_DESKTOP(total += iobuf.out_pos;) |
103 | IF_DESKTOP(total += outpos;) | 89 | iobuf.out_pos = 0; |
104 | } | 90 | } |
105 | if (r == XZ_STREAM_END | 91 | if (r == XZ_STREAM_END) { |
106 | /* this happens even with well-formed files: */ | ||
107 | || (r == XZ_BUF_ERROR && insz == 0 && outpos == 0) | ||
108 | ) { | ||
109 | break; | 92 | break; |
110 | } | 93 | } |
111 | if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) { | 94 | if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) { |
112 | bb_error_msg("corrupted data"); | 95 | bb_error_msg("corrupted or unsupported data"); |
113 | total = -1; | 96 | total = -1; |
114 | break; | 97 | break; |
115 | } | 98 | } |
116 | iobuf.out_pos = 0; | ||
117 | } | 99 | } |
118 | xz_dec_end(state); | 100 | xz_dec_end(state); |
119 | free(membuf); | 101 | free(membuf); |
diff --git a/archival/libunarchive/unxz/xz.h b/archival/libunarchive/unxz/xz.h index eb82706b9..c6c071c4a 100644 --- a/archival/libunarchive/unxz/xz.h +++ b/archival/libunarchive/unxz/xz.h | |||
@@ -30,9 +30,42 @@ | |||
30 | #endif | 30 | #endif |
31 | 31 | ||
32 | /** | 32 | /** |
33 | * enum xz_mode - Operation mode | ||
34 | * | ||
35 | * @XZ_SINGLE: Single-call mode. This uses less RAM than | ||
36 | * than multi-call modes, because the LZMA2 | ||
37 | * dictionary doesn't need to be allocated as | ||
38 | * part of the decoder state. All required data | ||
39 | * structures are allocated at initialization, | ||
40 | * so xz_dec_run() cannot return XZ_MEM_ERROR. | ||
41 | * @XZ_PREALLOC: Multi-call mode with preallocated LZMA2 | ||
42 | * dictionary buffer. All data structures are | ||
43 | * allocated at initialization, so xz_dec_run() | ||
44 | * cannot return XZ_MEM_ERROR. | ||
45 | * @XZ_DYNALLOC: Multi-call mode. The LZMA2 dictionary is | ||
46 | * allocated once the required size has been | ||
47 | * parsed from the stream headers. If the | ||
48 | * allocation fails, xz_dec_run() will return | ||
49 | * XZ_MEM_ERROR. | ||
50 | * | ||
51 | * It is possible to enable support only for a subset of the above | ||
52 | * modes at compile time by defining XZ_DEC_SINGLE, XZ_DEC_PREALLOC, | ||
53 | * or XZ_DEC_DYNALLOC. The xz_dec kernel module is always compiled | ||
54 | * with support for all operation modes, but the preboot code may | ||
55 | * be built with fewer features to minimize code size. | ||
56 | */ | ||
57 | enum xz_mode { | ||
58 | XZ_SINGLE, | ||
59 | XZ_PREALLOC, | ||
60 | XZ_DYNALLOC | ||
61 | }; | ||
62 | |||
63 | /** | ||
33 | * enum xz_ret - Return codes | 64 | * enum xz_ret - Return codes |
34 | * @XZ_OK: Everything is OK so far. More input or more | 65 | * @XZ_OK: Everything is OK so far. More input or more |
35 | * output space is required to continue. | 66 | * output space is required to continue. This |
67 | * return code is possible only in multi-call mode | ||
68 | * (XZ_PREALLOC or XZ_DYNALLOC). | ||
36 | * @XZ_STREAM_END: Operation finished successfully. | 69 | * @XZ_STREAM_END: Operation finished successfully. |
37 | * @XZ_UNSUPPORTED_CHECK: Integrity check type is not supported. Decoding | 70 | * @XZ_UNSUPPORTED_CHECK: Integrity check type is not supported. Decoding |
38 | * is still possible in multi-call mode by simply | 71 | * is still possible in multi-call mode by simply |
@@ -42,8 +75,17 @@ | |||
42 | * which is not used in the kernel. Unsupported | 75 | * which is not used in the kernel. Unsupported |
43 | * check types return XZ_OPTIONS_ERROR if | 76 | * check types return XZ_OPTIONS_ERROR if |
44 | * XZ_DEC_ANY_CHECK was not defined at build time. | 77 | * XZ_DEC_ANY_CHECK was not defined at build time. |
45 | * @XZ_MEMLIMIT_ERROR: Not enough memory was preallocated at decoder | 78 | * @XZ_MEM_ERROR: Allocating memory failed. This return code is |
46 | * initialization time. | 79 | * possible only if the decoder was initialized |
80 | * with XZ_DYNALLOC. The amount of memory that was | ||
81 | * tried to be allocated was no more than the | ||
82 | * dict_max argument given to xz_dec_init(). | ||
83 | * @XZ_MEMLIMIT_ERROR: A bigger LZMA2 dictionary would be needed than | ||
84 | * allowed by the dict_max argument given to | ||
85 | * xz_dec_init(). This return value is possible | ||
86 | * only in multi-call mode (XZ_PREALLOC or | ||
87 | * XZ_DYNALLOC); the single-call mode (XZ_SINGLE) | ||
88 | * ignores the dict_max argument. | ||
47 | * @XZ_FORMAT_ERROR: File format was not recognized (wrong magic | 89 | * @XZ_FORMAT_ERROR: File format was not recognized (wrong magic |
48 | * bytes). | 90 | * bytes). |
49 | * @XZ_OPTIONS_ERROR: This implementation doesn't support the requested | 91 | * @XZ_OPTIONS_ERROR: This implementation doesn't support the requested |
@@ -72,6 +114,7 @@ enum xz_ret { | |||
72 | XZ_OK, | 114 | XZ_OK, |
73 | XZ_STREAM_END, | 115 | XZ_STREAM_END, |
74 | XZ_UNSUPPORTED_CHECK, | 116 | XZ_UNSUPPORTED_CHECK, |
117 | XZ_MEM_ERROR, | ||
75 | XZ_MEMLIMIT_ERROR, | 118 | XZ_MEMLIMIT_ERROR, |
76 | XZ_FORMAT_ERROR, | 119 | XZ_FORMAT_ERROR, |
77 | XZ_OPTIONS_ERROR, | 120 | XZ_OPTIONS_ERROR, |
@@ -112,61 +155,67 @@ struct xz_dec; | |||
112 | 155 | ||
113 | /** | 156 | /** |
114 | * xz_dec_init() - Allocate and initialize a XZ decoder state | 157 | * xz_dec_init() - Allocate and initialize a XZ decoder state |
158 | * @mode: Operation mode | ||
115 | * @dict_max: Maximum size of the LZMA2 dictionary (history buffer) for | 159 | * @dict_max: Maximum size of the LZMA2 dictionary (history buffer) for |
116 | * multi-call decoding, or special value of zero to indicate | 160 | * multi-call decoding. This is ignored in single-call mode |
117 | * single-call decoding mode. | 161 | * (mode == XZ_SINGLE). LZMA2 dictionary is always 2^n bytes |
118 | * | 162 | * or 2^n + 2^(n-1) bytes (the latter sizes are less common |
119 | * If dict_max > 0, the decoder is initialized to work in multi-call mode. | 163 | * in practice), so other values for dict_max don't make sense. |
120 | * dict_max number of bytes of memory is preallocated for the LZMA2 | 164 | * In the kernel, dictionary sizes of 64 KiB, 128 KiB, 256 KiB, |
121 | * dictionary. This way there is no risk that xz_dec_run() could run out | 165 | * 512 KiB, and 1 MiB are probably the only reasonable values, |
122 | * of memory, since xz_dec_run() will never allocate any memory. Instead, | 166 | * except for kernel and initramfs images where a bigger |
123 | * if the preallocated dictionary is too small for decoding the given input | 167 | * dictionary can be fine and useful. |
124 | * stream, xz_dec_run() will return XZ_MEMLIMIT_ERROR. Thus, it is important | 168 | * |
125 | * to know what kind of data will be decoded to avoid allocating excessive | 169 | * Single-call mode (XZ_SINGLE): xz_dec_run() decodes the whole stream at |
126 | * amount of memory for the dictionary. | 170 | * once. The caller must provide enough output space or the decoding will |
127 | * | 171 | * fail. The output space is used as the dictionary buffer, which is why |
128 | * LZMA2 dictionary is always 2^n bytes or 2^n + 2^(n-1) bytes (the latter | 172 | * there is no need to allocate the dictionary as part of the decoder's |
129 | * sizes are less common in practice). In the kernel, dictionary sizes of | 173 | * internal state. |
130 | * 64 KiB, 128 KiB, 256 KiB, 512 KiB, and 1 MiB are probably the only | ||
131 | * reasonable values. | ||
132 | * | ||
133 | * If dict_max == 0, the decoder is initialized to work in single-call mode. | ||
134 | * In single-call mode, xz_dec_run() decodes the whole stream at once. The | ||
135 | * caller must provide enough output space or the decoding will fail. The | ||
136 | * output space is used as the dictionary buffer, which is why there is | ||
137 | * no need to allocate the dictionary as part of the decoder's internal | ||
138 | * state. | ||
139 | * | 174 | * |
140 | * Because the output buffer is used as the workspace, streams encoded using | 175 | * Because the output buffer is used as the workspace, streams encoded using |
141 | * a big dictionary are not a problem in single-call. It is enough that the | 176 | * a big dictionary are not a problem in single-call mode. It is enough that |
142 | * output buffer is big enough to hold the actual uncompressed data; it | 177 | * the output buffer is big enough to hold the actual uncompressed data; it |
143 | * can be smaller than the dictionary size stored in the stream headers. | 178 | * can be smaller than the dictionary size stored in the stream headers. |
144 | * | 179 | * |
180 | * Multi-call mode with preallocated dictionary (XZ_PREALLOC): dict_max bytes | ||
181 | * of memory is preallocated for the LZMA2 dictionary. This way there is no | ||
182 | * risk that xz_dec_run() could run out of memory, since xz_dec_run() will | ||
183 | * never allocate any memory. Instead, if the preallocated dictionary is too | ||
184 | * small for decoding the given input stream, xz_dec_run() will return | ||
185 | * XZ_MEMLIMIT_ERROR. Thus, it is important to know what kind of data will be | ||
186 | * decoded to avoid allocating excessive amount of memory for the dictionary. | ||
187 | * | ||
188 | * Multi-call mode with dynamically allocated dictionary (XZ_DYNALLOC): | ||
189 | * dict_max specifies the maximum allowed dictionary size that xz_dec_run() | ||
190 | * may allocate once it has parsed the dictionary size from the stream | ||
191 | * headers. This way excessive allocations can be avoided while still | ||
192 | * limiting the maximum memory usage to a sane value to prevent running the | ||
193 | * system out of memory when decompressing streams from untrusted sources. | ||
194 | * | ||
145 | * On success, xz_dec_init() returns a pointer to struct xz_dec, which is | 195 | * On success, xz_dec_init() returns a pointer to struct xz_dec, which is |
146 | * ready to be used with xz_dec_run(). On error, xz_dec_init() returns NULL. | 196 | * ready to be used with xz_dec_run(). If memory allocation fails, |
197 | * xz_dec_init() returns NULL. | ||
147 | */ | 198 | */ |
148 | XZ_EXTERN struct xz_dec * XZ_FUNC xz_dec_init(uint32_t dict_max); | 199 | XZ_EXTERN struct xz_dec * XZ_FUNC xz_dec_init( |
200 | enum xz_mode mode, uint32_t dict_max); | ||
149 | 201 | ||
150 | /** | 202 | /** |
151 | * xz_dec_run() - Run the XZ decoder | 203 | * xz_dec_run() - Run the XZ decoder |
152 | * @s: Decoder state allocated using xz_dec_init() | 204 | * @s: Decoder state allocated using xz_dec_init() |
153 | * @b: Input and output buffers | 205 | * @b: Input and output buffers |
154 | * | 206 | * |
155 | * In multi-call mode, this function may return any of the values listed in | 207 | * The possible return values depend on build options and operation mode. |
156 | * enum xz_ret. | 208 | * See enum xz_ret for details. |
157 | * | 209 | * |
158 | * In single-call mode, this function never returns XZ_OK. If an error occurs | 210 | * NOTE: If an error occurs in single-call mode (return value is not |
159 | * in single-call mode (return value is not XZ_STREAM_END), b->in_pos and | 211 | * XZ_STREAM_END), b->in_pos and b->out_pos are not modified, and the |
160 | * b->out_pos are not modified, and the contents of the output buffer from | 212 | * contents of the output buffer from b->out[b->out_pos] onward are |
161 | * b->out[b->out_pos] onward are undefined. | 213 | * undefined. This is true even after XZ_BUF_ERROR, because with some filter |
162 | * | 214 | * chains, there may be a second pass over the output buffer, and this pass |
163 | * NOTE: In single-call mode, the contents of the output buffer are undefined | 215 | * cannot be properly done if the output buffer is truncated. Thus, you |
164 | * also after XZ_BUF_ERROR. This is because with some filter chains, there | 216 | * cannot give the single-call decoder a too small buffer and then expect to |
165 | * may be a second pass over the output buffer, and this pass cannot be | 217 | * get that amount valid data from the beginning of the stream. You must use |
166 | * properly done if the output buffer is truncated. Thus, you cannot give | 218 | * the multi-call decoder if you don't want to uncompress the whole stream. |
167 | * the single-call decoder a too small buffer and then expect to get that | ||
168 | * amount valid data from the beginning of the stream. You must use the | ||
169 | * multi-call decoder if you don't want to uncompress the whole stream. | ||
170 | */ | 219 | */ |
171 | XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b); | 220 | XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b); |
172 | 221 | ||
diff --git a/archival/libunarchive/unxz/xz_dec_lzma2.c b/archival/libunarchive/unxz/xz_dec_lzma2.c index 37de6fc32..da71cb4d4 100644 --- a/archival/libunarchive/unxz/xz_dec_lzma2.c +++ b/archival/libunarchive/unxz/xz_dec_lzma2.c | |||
@@ -34,7 +34,8 @@ | |||
34 | * | 34 | * |
35 | * In multi-call mode, also these are true: | 35 | * In multi-call mode, also these are true: |
36 | * end == size | 36 | * end == size |
37 | * size <= allocated | 37 | * size <= size_max |
38 | * allocated <= size | ||
38 | * | 39 | * |
39 | * Most of these variables are size_t to support single-call mode, | 40 | * Most of these variables are size_t to support single-call mode, |
40 | * in which the dictionary variables address the actual output | 41 | * in which the dictionary variables address the actual output |
@@ -74,11 +75,20 @@ struct dictionary { | |||
74 | uint32_t size; | 75 | uint32_t size; |
75 | 76 | ||
76 | /* | 77 | /* |
77 | * Amount of memory allocated for the dictionary. A special | 78 | * Maximum allowed dictionary size in multi-call mode. |
78 | * value of zero indicates that we are in single-call mode, | 79 | * This is ignored in single-call mode. |
79 | * where the output buffer works as the dictionary. | 80 | */ |
81 | uint32_t size_max; | ||
82 | |||
83 | /* | ||
84 | * Amount of memory currently allocated for the dictionary. | ||
85 | * This is used only with XZ_DYNALLOC. (With XZ_PREALLOC, | ||
86 | * size_max is always the same as the allocated size.) | ||
80 | */ | 87 | */ |
81 | uint32_t allocated; | 88 | uint32_t allocated; |
89 | |||
90 | /* Operation mode */ | ||
91 | enum xz_mode mode; | ||
82 | }; | 92 | }; |
83 | 93 | ||
84 | /* Range decoder */ | 94 | /* Range decoder */ |
@@ -120,31 +130,31 @@ struct lzma_len_dec { | |||
120 | }; | 130 | }; |
121 | 131 | ||
122 | struct lzma_dec { | 132 | struct lzma_dec { |
123 | /* | ||
124 | * LZMA properties or related bit masks (number of literal | ||
125 | * context bits, a mask dervied from the number of literal | ||
126 | * position bits, and a mask dervied from the number | ||
127 | * position bits) | ||
128 | */ | ||
129 | uint32_t lc; | ||
130 | uint32_t literal_pos_mask; /* (1 << lp) - 1 */ | ||
131 | uint32_t pos_mask; /* (1 << pb) - 1 */ | ||
132 | |||
133 | /* Types of the most recently seen LZMA symbols */ | ||
134 | enum lzma_state state; | ||
135 | |||
136 | /* Distances of latest four matches */ | 133 | /* Distances of latest four matches */ |
137 | uint32_t rep0; | 134 | uint32_t rep0; |
138 | uint32_t rep1; | 135 | uint32_t rep1; |
139 | uint32_t rep2; | 136 | uint32_t rep2; |
140 | uint32_t rep3; | 137 | uint32_t rep3; |
141 | 138 | ||
139 | /* Types of the most recently seen LZMA symbols */ | ||
140 | enum lzma_state state; | ||
141 | |||
142 | /* | 142 | /* |
143 | * Length of a match. This is updated so that dict_repeat can | 143 | * Length of a match. This is updated so that dict_repeat can |
144 | * be called again to finish repeating the whole match. | 144 | * be called again to finish repeating the whole match. |
145 | */ | 145 | */ |
146 | uint32_t len; | 146 | uint32_t len; |
147 | 147 | ||
148 | /* | ||
149 | * LZMA properties or related bit masks (number of literal | ||
150 | * context bits, a mask dervied from the number of literal | ||
151 | * position bits, and a mask dervied from the number | ||
152 | * position bits) | ||
153 | */ | ||
154 | uint32_t lc; | ||
155 | uint32_t literal_pos_mask; /* (1 << lp) - 1 */ | ||
156 | uint32_t pos_mask; /* (1 << pb) - 1 */ | ||
157 | |||
148 | /* If 1, it's a match. Otherwise it's a single 8-bit literal. */ | 158 | /* If 1, it's a match. Otherwise it's a single 8-bit literal. */ |
149 | uint16_t is_match[STATES][POS_STATES_MAX]; | 159 | uint16_t is_match[STATES][POS_STATES_MAX]; |
150 | 160 | ||
@@ -201,49 +211,59 @@ struct lzma_dec { | |||
201 | uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE]; | 211 | uint16_t literal[LITERAL_CODERS_MAX][LITERAL_CODER_SIZE]; |
202 | }; | 212 | }; |
203 | 213 | ||
214 | struct lzma2_dec { | ||
215 | /* Position in xz_dec_lzma2_run(). */ | ||
216 | enum lzma2_seq { | ||
217 | SEQ_CONTROL, | ||
218 | SEQ_UNCOMPRESSED_1, | ||
219 | SEQ_UNCOMPRESSED_2, | ||
220 | SEQ_COMPRESSED_0, | ||
221 | SEQ_COMPRESSED_1, | ||
222 | SEQ_PROPERTIES, | ||
223 | SEQ_LZMA_PREPARE, | ||
224 | SEQ_LZMA_RUN, | ||
225 | SEQ_COPY | ||
226 | } sequence; | ||
227 | |||
228 | /* Next position after decoding the compressed size of the chunk. */ | ||
229 | enum lzma2_seq next_sequence; | ||
230 | |||
231 | /* Uncompressed size of LZMA chunk (2 MiB at maximum) */ | ||
232 | uint32_t uncompressed; | ||
233 | |||
234 | /* | ||
235 | * Compressed size of LZMA chunk or compressed/uncompressed | ||
236 | * size of uncompressed chunk (64 KiB at maximum) | ||
237 | */ | ||
238 | uint32_t compressed; | ||
239 | |||
240 | /* | ||
241 | * True if dictionary reset is needed. This is false before | ||
242 | * the first chunk (LZMA or uncompressed). | ||
243 | */ | ||
244 | bool need_dict_reset; | ||
245 | |||
246 | /* | ||
247 | * True if new LZMA properties are needed. This is false | ||
248 | * before the first LZMA chunk. | ||
249 | */ | ||
250 | bool need_props; | ||
251 | }; | ||
252 | |||
204 | struct xz_dec_lzma2 { | 253 | struct xz_dec_lzma2 { |
205 | /* LZMA2 */ | 254 | /* |
206 | struct { | 255 | * The order below is important on x86 to reduce code size and |
207 | /* Position in xz_dec_lzma2_run(). */ | 256 | * it shouldn't hurt on other platforms. Everything up to and |
208 | enum lzma2_seq { | 257 | * including lzma.pos_mask are in the first 128 bytes on x86-32, |
209 | SEQ_CONTROL, | 258 | * which allows using smaller instructions to access those |
210 | SEQ_UNCOMPRESSED_1, | 259 | * variables. On x86-64, fewer variables fit into the first 128 |
211 | SEQ_UNCOMPRESSED_2, | 260 | * bytes, but this is still the best order without sacrificing |
212 | SEQ_COMPRESSED_0, | 261 | * the readability by splitting the structures. |
213 | SEQ_COMPRESSED_1, | 262 | */ |
214 | SEQ_PROPERTIES, | 263 | struct rc_dec rc; |
215 | SEQ_LZMA_PREPARE, | 264 | struct dictionary dict; |
216 | SEQ_LZMA_RUN, | 265 | struct lzma2_dec lzma2; |
217 | SEQ_COPY | 266 | struct lzma_dec lzma; |
218 | } sequence; | ||
219 | |||
220 | /* | ||
221 | * Next position after decoding the compressed size of | ||
222 | * the chunk. | ||
223 | */ | ||
224 | enum lzma2_seq next_sequence; | ||
225 | |||
226 | /* Uncompressed size of LZMA chunk (2 MiB at maximum) */ | ||
227 | uint32_t uncompressed; | ||
228 | |||
229 | /* | ||
230 | * Compressed size of LZMA chunk or compressed/uncompressed | ||
231 | * size of uncompressed chunk (64 KiB at maximum) | ||
232 | */ | ||
233 | uint32_t compressed; | ||
234 | |||
235 | /* | ||
236 | * True if dictionary reset is needed. This is false before | ||
237 | * the first chunk (LZMA or uncompressed). | ||
238 | */ | ||
239 | bool need_dict_reset; | ||
240 | |||
241 | /* | ||
242 | * True if new LZMA properties are needed. This is false | ||
243 | * before the first LZMA chunk. | ||
244 | */ | ||
245 | bool need_props; | ||
246 | } lzma2; | ||
247 | 267 | ||
248 | /* | 268 | /* |
249 | * Temporary buffer which holds small number of input bytes between | 269 | * Temporary buffer which holds small number of input bytes between |
@@ -253,10 +273,6 @@ struct xz_dec_lzma2 { | |||
253 | uint32_t size; | 273 | uint32_t size; |
254 | uint8_t buf[3 * LZMA_IN_REQUIRED]; | 274 | uint8_t buf[3 * LZMA_IN_REQUIRED]; |
255 | } temp; | 275 | } temp; |
256 | |||
257 | struct dictionary dict; | ||
258 | struct rc_dec rc; | ||
259 | struct lzma_dec lzma; | ||
260 | }; | 276 | }; |
261 | 277 | ||
262 | /************** | 278 | /************** |
@@ -269,7 +285,7 @@ struct xz_dec_lzma2 { | |||
269 | */ | 285 | */ |
270 | static void XZ_FUNC dict_reset(struct dictionary *dict, struct xz_buf *b) | 286 | static void XZ_FUNC dict_reset(struct dictionary *dict, struct xz_buf *b) |
271 | { | 287 | { |
272 | if (dict->allocated == 0) { | 288 | if (DEC_IS_SINGLE(dict->mode)) { |
273 | dict->buf = b->out + b->out_pos; | 289 | dict->buf = b->out + b->out_pos; |
274 | dict->end = b->out_size - b->out_pos; | 290 | dict->end = b->out_size - b->out_pos; |
275 | } | 291 | } |
@@ -379,7 +395,7 @@ static void XZ_FUNC dict_uncompressed( | |||
379 | if (dict->full < dict->pos) | 395 | if (dict->full < dict->pos) |
380 | dict->full = dict->pos; | 396 | dict->full = dict->pos; |
381 | 397 | ||
382 | if (dict->allocated != 0) { | 398 | if (DEC_IS_MULTI(dict->mode)) { |
383 | if (dict->pos == dict->end) | 399 | if (dict->pos == dict->end) |
384 | dict->pos = 0; | 400 | dict->pos = 0; |
385 | 401 | ||
@@ -404,7 +420,7 @@ static uint32_t XZ_FUNC dict_flush(struct dictionary *dict, struct xz_buf *b) | |||
404 | { | 420 | { |
405 | size_t copy_size = dict->pos - dict->start; | 421 | size_t copy_size = dict->pos - dict->start; |
406 | 422 | ||
407 | if (dict->allocated != 0) { | 423 | if (DEC_IS_MULTI(dict->mode)) { |
408 | if (dict->pos == dict->end) | 424 | if (dict->pos == dict->end) |
409 | dict->pos = 0; | 425 | dict->pos = 0; |
410 | 426 | ||
@@ -422,7 +438,7 @@ static uint32_t XZ_FUNC dict_flush(struct dictionary *dict, struct xz_buf *b) | |||
422 | *****************/ | 438 | *****************/ |
423 | 439 | ||
424 | /* Reset the range decoder. */ | 440 | /* Reset the range decoder. */ |
425 | static __always_inline void XZ_FUNC rc_reset(struct rc_dec *rc) | 441 | static void XZ_FUNC rc_reset(struct rc_dec *rc) |
426 | { | 442 | { |
427 | rc->range = (uint32_t)-1; | 443 | rc->range = (uint32_t)-1; |
428 | rc->code = 0; | 444 | rc->code = 0; |
@@ -1088,28 +1104,27 @@ XZ_EXTERN NOINLINE enum xz_ret XZ_FUNC xz_dec_lzma2_run( | |||
1088 | return XZ_OK; | 1104 | return XZ_OK; |
1089 | } | 1105 | } |
1090 | 1106 | ||
1091 | XZ_EXTERN struct xz_dec_lzma2 * XZ_FUNC xz_dec_lzma2_create(uint32_t dict_max) | 1107 | XZ_EXTERN struct xz_dec_lzma2 * XZ_FUNC xz_dec_lzma2_create( |
1108 | enum xz_mode mode, uint32_t dict_max) | ||
1092 | { | 1109 | { |
1093 | struct xz_dec_lzma2 *s; | 1110 | struct xz_dec_lzma2 *s = kmalloc(sizeof(*s), GFP_KERNEL); |
1094 | |||
1095 | /* Maximum supported dictionary by this implementation is 3 GiB. */ | ||
1096 | if (dict_max > ((uint32_t)3 << 30)) | ||
1097 | return NULL; | ||
1098 | |||
1099 | s = kmalloc(sizeof(*s), GFP_KERNEL); | ||
1100 | if (s == NULL) | 1111 | if (s == NULL) |
1101 | return NULL; | 1112 | return NULL; |
1102 | 1113 | ||
1103 | if (dict_max > 0) { | 1114 | s->dict.mode = mode; |
1115 | s->dict.size_max = dict_max; | ||
1116 | |||
1117 | if (DEC_IS_PREALLOC(mode)) { | ||
1104 | s->dict.buf = vmalloc(dict_max); | 1118 | s->dict.buf = vmalloc(dict_max); |
1105 | if (s->dict.buf == NULL) { | 1119 | if (s->dict.buf == NULL) { |
1106 | kfree(s); | 1120 | kfree(s); |
1107 | return NULL; | 1121 | return NULL; |
1108 | } | 1122 | } |
1123 | } else if (DEC_IS_DYNALLOC(mode)) { | ||
1124 | s->dict.buf = NULL; | ||
1125 | s->dict.allocated = 0; | ||
1109 | } | 1126 | } |
1110 | 1127 | ||
1111 | s->dict.allocated = dict_max; | ||
1112 | |||
1113 | return s; | 1128 | return s; |
1114 | } | 1129 | } |
1115 | 1130 | ||
@@ -1123,18 +1138,23 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_lzma2_reset( | |||
1123 | s->dict.size = 2 + (props & 1); | 1138 | s->dict.size = 2 + (props & 1); |
1124 | s->dict.size <<= (props >> 1) + 11; | 1139 | s->dict.size <<= (props >> 1) + 11; |
1125 | 1140 | ||
1126 | if (s->dict.allocated > 0 && s->dict.allocated < s->dict.size) { | 1141 | if (DEC_IS_MULTI(s->dict.mode)) { |
1127 | #ifdef XZ_REALLOC_DICT_BUF | 1142 | if (s->dict.size > s->dict.size_max) |
1128 | s->dict.buf = XZ_REALLOC_DICT_BUF(s->dict.buf, s->dict.size); | 1143 | return XZ_MEMLIMIT_ERROR; |
1129 | if (!s->dict.buf) | ||
1130 | return XZ_MEMLIMIT_ERROR; | ||
1131 | s->dict.allocated = s->dict.size; | ||
1132 | #else | ||
1133 | return XZ_MEMLIMIT_ERROR; | ||
1134 | #endif | ||
1135 | } | ||
1136 | 1144 | ||
1137 | s->dict.end = s->dict.size; | 1145 | s->dict.end = s->dict.size; |
1146 | |||
1147 | if (DEC_IS_DYNALLOC(s->dict.mode)) { | ||
1148 | if (s->dict.allocated < s->dict.size) { | ||
1149 | vfree(s->dict.buf); | ||
1150 | s->dict.buf = vmalloc(s->dict.size); | ||
1151 | if (s->dict.buf == NULL) { | ||
1152 | s->dict.allocated = 0; | ||
1153 | return XZ_MEM_ERROR; | ||
1154 | } | ||
1155 | } | ||
1156 | } | ||
1157 | } | ||
1138 | 1158 | ||
1139 | s->lzma.len = 0; | 1159 | s->lzma.len = 0; |
1140 | 1160 | ||
@@ -1148,7 +1168,7 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_lzma2_reset( | |||
1148 | 1168 | ||
1149 | XZ_EXTERN void XZ_FUNC xz_dec_lzma2_end(struct xz_dec_lzma2 *s) | 1169 | XZ_EXTERN void XZ_FUNC xz_dec_lzma2_end(struct xz_dec_lzma2 *s) |
1150 | { | 1170 | { |
1151 | if (s->dict.allocated > 0) | 1171 | if (DEC_IS_MULTI(s->dict.mode)) |
1152 | vfree(s->dict.buf); | 1172 | vfree(s->dict.buf); |
1153 | 1173 | ||
1154 | kfree(s); | 1174 | kfree(s); |
diff --git a/archival/libunarchive/unxz/xz_dec_stream.c b/archival/libunarchive/unxz/xz_dec_stream.c index 21db283fb..bdcbf1ba3 100644 --- a/archival/libunarchive/unxz/xz_dec_stream.c +++ b/archival/libunarchive/unxz/xz_dec_stream.c | |||
@@ -48,8 +48,8 @@ struct xz_dec { | |||
48 | /* Type of the integrity check calculated from uncompressed data */ | 48 | /* Type of the integrity check calculated from uncompressed data */ |
49 | enum xz_check check_type; | 49 | enum xz_check check_type; |
50 | 50 | ||
51 | /* True if we are operating in single-call mode. */ | 51 | /* Operation mode */ |
52 | bool single_call; | 52 | enum xz_mode mode; |
53 | 53 | ||
54 | /* | 54 | /* |
55 | * True if the next call to xz_dec_run() is allowed to return | 55 | * True if the next call to xz_dec_run() is allowed to return |
@@ -737,14 +737,14 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b) | |||
737 | size_t out_start; | 737 | size_t out_start; |
738 | enum xz_ret ret; | 738 | enum xz_ret ret; |
739 | 739 | ||
740 | if (s->single_call) | 740 | if (DEC_IS_SINGLE(s->mode)) |
741 | xz_dec_reset(s); | 741 | xz_dec_reset(s); |
742 | 742 | ||
743 | in_start = b->in_pos; | 743 | in_start = b->in_pos; |
744 | out_start = b->out_pos; | 744 | out_start = b->out_pos; |
745 | ret = dec_main(s, b); | 745 | ret = dec_main(s, b); |
746 | 746 | ||
747 | if (s->single_call) { | 747 | if (DEC_IS_SINGLE(s->mode)) { |
748 | if (ret == XZ_OK) | 748 | if (ret == XZ_OK) |
749 | ret = b->in_pos == b->in_size | 749 | ret = b->in_pos == b->in_size |
750 | ? XZ_DATA_ERROR : XZ_BUF_ERROR; | 750 | ? XZ_DATA_ERROR : XZ_BUF_ERROR; |
@@ -767,21 +767,22 @@ XZ_EXTERN enum xz_ret XZ_FUNC xz_dec_run(struct xz_dec *s, struct xz_buf *b) | |||
767 | return ret; | 767 | return ret; |
768 | } | 768 | } |
769 | 769 | ||
770 | XZ_EXTERN struct xz_dec * XZ_FUNC xz_dec_init(uint32_t dict_max) | 770 | XZ_EXTERN struct xz_dec * XZ_FUNC xz_dec_init( |
771 | enum xz_mode mode, uint32_t dict_max) | ||
771 | { | 772 | { |
772 | struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL); | 773 | struct xz_dec *s = kmalloc(sizeof(*s), GFP_KERNEL); |
773 | if (s == NULL) | 774 | if (s == NULL) |
774 | return NULL; | 775 | return NULL; |
775 | 776 | ||
776 | s->single_call = dict_max == 0; | 777 | s->mode = mode; |
777 | 778 | ||
778 | #ifdef XZ_DEC_BCJ | 779 | #ifdef XZ_DEC_BCJ |
779 | s->bcj = xz_dec_bcj_create(s->single_call); | 780 | s->bcj = xz_dec_bcj_create(DEC_IS_SINGLE(mode)); |
780 | if (s->bcj == NULL) | 781 | if (s->bcj == NULL) |
781 | goto error_bcj; | 782 | goto error_bcj; |
782 | #endif | 783 | #endif |
783 | 784 | ||
784 | s->lzma2 = xz_dec_lzma2_create(dict_max); | 785 | s->lzma2 = xz_dec_lzma2_create(mode, dict_max); |
785 | if (s->lzma2 == NULL) | 786 | if (s->lzma2 == NULL) |
786 | goto error_lzma2; | 787 | goto error_lzma2; |
787 | 788 | ||
diff --git a/archival/libunarchive/unxz/xz_private.h b/archival/libunarchive/unxz/xz_private.h index f4e0b4010..145649a83 100644 --- a/archival/libunarchive/unxz/xz_private.h +++ b/archival/libunarchive/unxz/xz_private.h | |||
@@ -53,6 +53,45 @@ | |||
53 | # include "xz_config.h" | 53 | # include "xz_config.h" |
54 | #endif | 54 | #endif |
55 | 55 | ||
56 | /* If no specific decoding mode is requested, enable support for all modes. */ | ||
57 | #if !defined(XZ_DEC_SINGLE) && !defined(XZ_DEC_PREALLOC) \ | ||
58 | && !defined(XZ_DEC_DYNALLOC) | ||
59 | # define XZ_DEC_SINGLE | ||
60 | # define XZ_DEC_PREALLOC | ||
61 | # define XZ_DEC_DYNALLOC | ||
62 | #endif | ||
63 | |||
64 | /* | ||
65 | * The DEC_IS_foo(mode) macros are used in "if" statements. If only some | ||
66 | * of the supported modes are enabled, these macros will evaluate to true or | ||
67 | * false at compile time and thus allow the compiler to omit unneeded code. | ||
68 | */ | ||
69 | #ifdef XZ_DEC_SINGLE | ||
70 | # define DEC_IS_SINGLE(mode) ((mode) == XZ_SINGLE) | ||
71 | #else | ||
72 | # define DEC_IS_SINGLE(mode) (false) | ||
73 | #endif | ||
74 | |||
75 | #ifdef XZ_DEC_PREALLOC | ||
76 | # define DEC_IS_PREALLOC(mode) ((mode) == XZ_PREALLOC) | ||
77 | #else | ||
78 | # define DEC_IS_PREALLOC(mode) (false) | ||
79 | #endif | ||
80 | |||
81 | #ifdef XZ_DEC_DYNALLOC | ||
82 | # define DEC_IS_DYNALLOC(mode) ((mode) == XZ_DYNALLOC) | ||
83 | #else | ||
84 | # define DEC_IS_DYNALLOC(mode) (false) | ||
85 | #endif | ||
86 | |||
87 | #if !defined(XZ_DEC_SINGLE) | ||
88 | # define DEC_IS_MULTI(mode) (true) | ||
89 | #elif defined(XZ_DEC_PREALLOC) || defined(XZ_DEC_DYNALLOC) | ||
90 | # define DEC_IS_MULTI(mode) ((mode) != XZ_SINGLE) | ||
91 | #else | ||
92 | # define DEC_IS_MULTI(mode) (false) | ||
93 | #endif | ||
94 | |||
56 | /* | 95 | /* |
57 | * If any of the BCJ filter decoders are wanted, define XZ_DEC_BCJ. | 96 | * If any of the BCJ filter decoders are wanted, define XZ_DEC_BCJ. |
58 | * XZ_DEC_BCJ is used to enable generic support for BCJ decoders. | 97 | * XZ_DEC_BCJ is used to enable generic support for BCJ decoders. |
@@ -71,7 +110,7 @@ | |||
71 | * before calling xz_dec_lzma2_run(). | 110 | * before calling xz_dec_lzma2_run(). |
72 | */ | 111 | */ |
73 | XZ_EXTERN struct xz_dec_lzma2 * XZ_FUNC xz_dec_lzma2_create( | 112 | XZ_EXTERN struct xz_dec_lzma2 * XZ_FUNC xz_dec_lzma2_create( |
74 | uint32_t dict_max); | 113 | enum xz_mode mode, uint32_t dict_max); |
75 | 114 | ||
76 | /* | 115 | /* |
77 | * Decode the LZMA2 properties (one byte) and reset the decoder. Return | 116 | * Decode the LZMA2 properties (one byte) and reset the decoder. Return |