Annotation of /trunk/busybox/patches/busybox-1.20.2-xz-multiple-streams.patch
Parent Directory | Revision Log
Revision 2435 -
(hide annotations)
(download)
Tue May 13 11:34:36 2014 UTC (10 years, 4 months ago) by niro
File size: 4318 byte(s)
Tue May 13 11:34:36 2014 UTC (10 years, 4 months ago) by niro
File size: 4318 byte(s)
-added xz multibple streams patch to fix >=linux-3.8 decompression
1 | niro | 2435 | http://git.tukaani.org/?p=xz-embedded.git;a=commitdiff;h=4cec51e1be4797a4bd8b266a1d34cabd7fdb79fd |
2 | --- busybox-1.20.2.org/archival/libarchive/unxz/xz_dec_lzma2.c | ||
3 | +++ busybox-1.20.2/archival/libarchive/unxz/xz_dec_lzma2.c | ||
4 | @@ -972,6 +972,9 @@ | ||
5 | */ | ||
6 | tmp = b->in[b->in_pos++]; | ||
7 | |||
8 | + if (tmp == 0x00) | ||
9 | + return XZ_STREAM_END; | ||
10 | + | ||
11 | if (tmp >= 0xE0 || tmp == 0x01) { | ||
12 | s->lzma2.need_props = true; | ||
13 | s->lzma2.need_dict_reset = false; | ||
14 | @@ -1004,9 +1007,6 @@ | ||
15 | lzma_reset(s); | ||
16 | } | ||
17 | } else { | ||
18 | - if (tmp == 0x00) | ||
19 | - return XZ_STREAM_END; | ||
20 | - | ||
21 | if (tmp > 0x02) | ||
22 | return XZ_DATA_ERROR; | ||
23 | |||
24 | http://git.tukaani.org/?p=xz-embedded.git;a=commitdiff;h=9690fe69dc97eb2e7fe2804e4448a5278cde5411 | ||
25 | --- busybox-1.20.2.org/archival/libarchive/unxz/xz_dec_bcj.c | ||
26 | +++ busybox-1.20.2/archival/libarchive/unxz/xz_dec_bcj.c | ||
27 | @@ -443,8 +443,12 @@ | ||
28 | * next filter in the chain. Apply the BCJ filter on the new data | ||
29 | * in the output buffer. If everything cannot be filtered, copy it | ||
30 | * to temp and rewind the output buffer position accordingly. | ||
31 | + * | ||
32 | + * This needs to be always run when temp.size == 0 to handle a special | ||
33 | + * case where the output buffer is full and the next filter has no | ||
34 | + * more output coming but hasn't returned XZ_STREAM_END yet. | ||
35 | */ | ||
36 | - if (s->temp.size < b->out_size - b->out_pos) { | ||
37 | + if (s->temp.size < b->out_size - b->out_pos || s->temp.size == 0) { | ||
38 | out_start = b->out_pos; | ||
39 | memcpy(b->out + b->out_pos, s->temp.buf, s->temp.size); | ||
40 | b->out_pos += s->temp.size; | ||
41 | @@ -467,16 +471,25 @@ | ||
42 | s->temp.size = b->out_pos - out_start; | ||
43 | b->out_pos -= s->temp.size; | ||
44 | memcpy(s->temp.buf, b->out + b->out_pos, s->temp.size); | ||
45 | + | ||
46 | + /* | ||
47 | + * If there wasn't enough input to the next filter to fill | ||
48 | + * the output buffer with unfiltered data, there's no point | ||
49 | + * to try decoding more data to temp. | ||
50 | + */ | ||
51 | + if (b->out_pos + s->temp.size < b->out_size) | ||
52 | + return XZ_OK; | ||
53 | } | ||
54 | |||
55 | /* | ||
56 | - * If we have unfiltered data in temp, try to fill by decoding more | ||
57 | - * data from the next filter. Apply the BCJ filter on temp. Then we | ||
58 | - * hopefully can fill the actual output buffer by copying filtered | ||
59 | - * data from temp. A mix of filtered and unfiltered data may be left | ||
60 | - * in temp; it will be taken care on the next call to this function. | ||
61 | + * We have unfiltered data in temp. If the output buffer isn't full | ||
62 | + * yet, try to fill the temp buffer by decoding more data from the | ||
63 | + * next filter. Apply the BCJ filter on temp. Then we hopefully can | ||
64 | + * fill the actual output buffer by copying filtered data from temp. | ||
65 | + * A mix of filtered and unfiltered data may be left in temp; it will | ||
66 | + * be taken care on the next call to this function. | ||
67 | */ | ||
68 | - if (s->temp.size > 0) { | ||
69 | + if (b->out_pos < b->out_size) { | ||
70 | /* Make b->out{,_pos,_size} temporarily point to s->temp. */ | ||
71 | s->out = b->out; | ||
72 | s->out_pos = b->out_pos; | ||
73 | http://lists.busybox.net/pipermail/busybox/2013-February/078927.html | ||
74 | |||
75 | --- busybox-1.20.2.org/archival/libarchive/decompress_unxz.c | ||
76 | +++ busybox-1.20.2/archival/libarchive/decompress_unxz.c | ||
77 | @@ -86,8 +86,40 @@ | ||
78 | IF_DESKTOP(total += iobuf.out_pos;) | ||
79 | iobuf.out_pos = 0; | ||
80 | } | ||
81 | - if (r == XZ_STREAM_END) { | ||
82 | - break; | ||
83 | + while (r == XZ_STREAM_END) { | ||
84 | + /* Handle concatenated .xz Streams including possible | ||
85 | + * Stream Padding. | ||
86 | + */ | ||
87 | + if (iobuf.in_pos == iobuf.in_size) { | ||
88 | + int rd = safe_read(src_fd, membuf, BUFSIZ); | ||
89 | + if (rd < 0) { | ||
90 | + bb_error_msg(bb_msg_read_error); | ||
91 | + total = -1; | ||
92 | + goto out; | ||
93 | + } | ||
94 | + if (rd == 0) | ||
95 | + goto out; | ||
96 | + | ||
97 | + iobuf.in_size = rd; | ||
98 | + iobuf.in_pos = 0; | ||
99 | + } | ||
100 | + | ||
101 | + /* Stream Padding must always be a multiple of four | ||
102 | + * bytes to preserve four-byte alignment. To keep the | ||
103 | + * code slightly smaller, we aren't as strict here as | ||
104 | + * the .xz spec requires. We just skip all zero-bytes | ||
105 | + * without checking the alignment and thus can accept | ||
106 | + * files that aren't valid, e.g. the XZ Utils test | ||
107 | + * files bad-0pad-empty.xz and bad-0catpad-empty.xz. | ||
108 | + */ | ||
109 | + while (iobuf.in_pos < iobuf.in_size) { | ||
110 | + if (membuf[iobuf.in_pos] != 0) { | ||
111 | + xz_dec_reset(state); | ||
112 | + r = XZ_OK; | ||
113 | + break; | ||
114 | + } | ||
115 | + ++iobuf.in_pos; | ||
116 | + } | ||
117 | } | ||
118 | if (r != XZ_OK && r != XZ_UNSUPPORTED_CHECK) { | ||
119 | bb_error_msg("corrupted data"); | ||
120 | @@ -95,6 +127,8 @@ | ||
121 | break; | ||
122 | } | ||
123 | } | ||
124 | + | ||
125 | +out: | ||
126 | xz_dec_end(state); | ||
127 | free(membuf); | ||
128 |