diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2016-06-20 11:06:42 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2016-06-20 11:06:42 +0200 |
commit | 984b0a613aaf1cdf48c2e2af08c8466a7bad8307 (patch) | |
tree | 57b512d3843221b92da936b46abd238d1a036a94 | |
parent | ecf25cb5bce27ca5820e2895d8458f38c406d105 (diff) | |
download | busybox-w32-984b0a613aaf1cdf48c2e2af08c8466a7bad8307.tar.gz busybox-w32-984b0a613aaf1cdf48c2e2af08c8466a7bad8307.tar.bz2 busybox-w32-984b0a613aaf1cdf48c2e2af08c8466a7bad8307.zip |
libarchive: fix xmalloc_open_zipped_read_close() on NOMMU
The somewhat new "unpack in memory" code was broken
for xmalloc_open_zipped_read_close() on NOMMU: we seek back
over signature, but then expect it to be already consumed.
Stop seeking back in this case.
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | archival/bbunzip.c | 2 | ||||
-rw-r--r-- | archival/libarchive/decompress_gunzip.c | 4 | ||||
-rw-r--r-- | archival/libarchive/decompress_unxz.c | 2 | ||||
-rw-r--r-- | archival/libarchive/open_transformer.c | 35 | ||||
-rw-r--r-- | include/bb_archive.h | 8 |
5 files changed, 23 insertions, 28 deletions
diff --git a/archival/bbunzip.c b/archival/bbunzip.c index b4f754e0b..07ef8617e 100644 --- a/archival/bbunzip.c +++ b/archival/bbunzip.c | |||
@@ -121,7 +121,7 @@ int FAST_FUNC bbunpack(char **argv, | |||
121 | 121 | ||
122 | if (!(option_mask32 & SEAMLESS_MAGIC)) { | 122 | if (!(option_mask32 & SEAMLESS_MAGIC)) { |
123 | init_transformer_state(&xstate); | 123 | init_transformer_state(&xstate); |
124 | xstate.check_signature = 1; | 124 | xstate.signature_skipped = 0; |
125 | /*xstate.src_fd = STDIN_FILENO; - already is */ | 125 | /*xstate.src_fd = STDIN_FILENO; - already is */ |
126 | xstate.dst_fd = STDOUT_FILENO; | 126 | xstate.dst_fd = STDOUT_FILENO; |
127 | status = unpacker(&xstate); | 127 | status = unpacker(&xstate); |
diff --git a/archival/libarchive/decompress_gunzip.c b/archival/libarchive/decompress_gunzip.c index 20e4d9ac5..c7fa5b526 100644 --- a/archival/libarchive/decompress_gunzip.c +++ b/archival/libarchive/decompress_gunzip.c | |||
@@ -1201,7 +1201,7 @@ unpack_gz_stream(transformer_state_t *xstate) | |||
1201 | if (check_signature16(xstate, GZIP_MAGIC)) | 1201 | if (check_signature16(xstate, GZIP_MAGIC)) |
1202 | return -1; | 1202 | return -1; |
1203 | #else | 1203 | #else |
1204 | if (xstate->check_signature) { | 1204 | if (!xstate->signature_skipped) { |
1205 | uint16_t magic2; | 1205 | uint16_t magic2; |
1206 | 1206 | ||
1207 | if (full_read(xstate->src_fd, &magic2, 2) != 2) { | 1207 | if (full_read(xstate->src_fd, &magic2, 2) != 2) { |
@@ -1210,7 +1210,7 @@ unpack_gz_stream(transformer_state_t *xstate) | |||
1210 | return -1; | 1210 | return -1; |
1211 | } | 1211 | } |
1212 | if (magic2 == COMPRESS_MAGIC) { | 1212 | if (magic2 == COMPRESS_MAGIC) { |
1213 | xstate->check_signature = 0; | 1213 | xstate->signature_skipped = 2; |
1214 | return unpack_Z_stream(xstate); | 1214 | return unpack_Z_stream(xstate); |
1215 | } | 1215 | } |
1216 | if (magic2 != GZIP_MAGIC) | 1216 | if (magic2 != GZIP_MAGIC) |
diff --git a/archival/libarchive/decompress_unxz.c b/archival/libarchive/decompress_unxz.c index 1f408abfd..cd32cc745 100644 --- a/archival/libarchive/decompress_unxz.c +++ b/archival/libarchive/decompress_unxz.c | |||
@@ -55,7 +55,7 @@ unpack_xz_stream(transformer_state_t *xstate) | |||
55 | iobuf.out = membuf + BUFSIZ; | 55 | iobuf.out = membuf + BUFSIZ; |
56 | iobuf.out_size = BUFSIZ; | 56 | iobuf.out_size = BUFSIZ; |
57 | 57 | ||
58 | if (!xstate || xstate->check_signature == 0) { | 58 | if (!xstate || xstate->signature_skipped) { |
59 | /* Preload XZ file signature */ | 59 | /* Preload XZ file signature */ |
60 | strcpy((char*)membuf, HEADER_MAGIC); | 60 | strcpy((char*)membuf, HEADER_MAGIC); |
61 | iobuf.in_size = HEADER_MAGIC_SIZE; | 61 | iobuf.in_size = HEADER_MAGIC_SIZE; |
diff --git a/archival/libarchive/open_transformer.c b/archival/libarchive/open_transformer.c index be536a3d7..d93c8366f 100644 --- a/archival/libarchive/open_transformer.c +++ b/archival/libarchive/open_transformer.c | |||
@@ -13,16 +13,13 @@ void FAST_FUNC init_transformer_state(transformer_state_t *xstate) | |||
13 | 13 | ||
14 | int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16) | 14 | int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16) |
15 | { | 15 | { |
16 | if (xstate->check_signature) { | 16 | if (!xstate->signature_skipped) { |
17 | uint16_t magic2; | 17 | uint16_t magic2; |
18 | if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) { | 18 | if (full_read(xstate->src_fd, &magic2, 2) != 2 || magic2 != magic16) { |
19 | bb_error_msg("invalid magic"); | 19 | bb_error_msg("invalid magic"); |
20 | #if 0 /* possible future extension */ | ||
21 | if (xstate->check_signature > 1) | ||
22 | xfunc_die(); | ||
23 | #endif | ||
24 | return -1; | 20 | return -1; |
25 | } | 21 | } |
22 | xstate->signature_skipped = 2; | ||
26 | } | 23 | } |
27 | return 0; | 24 | return 0; |
28 | } | 25 | } |
@@ -102,7 +99,7 @@ void check_errors_in_children(int signo) | |||
102 | /* transformer(), more than meets the eye */ | 99 | /* transformer(), more than meets the eye */ |
103 | #if BB_MMU | 100 | #if BB_MMU |
104 | void FAST_FUNC fork_transformer(int fd, | 101 | void FAST_FUNC fork_transformer(int fd, |
105 | int check_signature, | 102 | int signature_skipped, |
106 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate) | 103 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate) |
107 | ) | 104 | ) |
108 | #else | 105 | #else |
@@ -123,7 +120,7 @@ void FAST_FUNC fork_transformer(int fd, const char *transform_prog) | |||
123 | IF_DESKTOP(long long) int r; | 120 | IF_DESKTOP(long long) int r; |
124 | transformer_state_t xstate; | 121 | transformer_state_t xstate; |
125 | init_transformer_state(&xstate); | 122 | init_transformer_state(&xstate); |
126 | xstate.check_signature = check_signature; | 123 | xstate.signature_skipped = signature_skipped; |
127 | xstate.src_fd = fd; | 124 | xstate.src_fd = fd; |
128 | xstate.dst_fd = fd_pipe.wr; | 125 | xstate.dst_fd = fd_pipe.wr; |
129 | r = transformer(&xstate); | 126 | r = transformer(&xstate); |
@@ -168,12 +165,11 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp | |||
168 | uint16_t b16[2]; | 165 | uint16_t b16[2]; |
169 | uint32_t b32[1]; | 166 | uint32_t b32[1]; |
170 | } magic; | 167 | } magic; |
171 | int offset; | ||
172 | transformer_state_t *xstate; | 168 | transformer_state_t *xstate; |
173 | 169 | ||
174 | offset = -2; | ||
175 | xstate = xzalloc(sizeof(*xstate)); | 170 | xstate = xzalloc(sizeof(*xstate)); |
176 | xstate->src_fd = fd; | 171 | xstate->src_fd = fd; |
172 | xstate->signature_skipped = 2; | ||
177 | 173 | ||
178 | /* .gz and .bz2 both have 2-byte signature, and their | 174 | /* .gz and .bz2 both have 2-byte signature, and their |
179 | * unpack_XXX_stream wants this header skipped. */ | 175 | * unpack_XXX_stream wants this header skipped. */ |
@@ -202,7 +198,7 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp | |||
202 | if (ENABLE_FEATURE_SEAMLESS_XZ | 198 | if (ENABLE_FEATURE_SEAMLESS_XZ |
203 | && magic.b16[0] == XZ_MAGIC1 | 199 | && magic.b16[0] == XZ_MAGIC1 |
204 | ) { | 200 | ) { |
205 | offset = -6; | 201 | xstate->signature_skipped = 6; |
206 | xread(fd, magic.b32, sizeof(magic.b32[0])); | 202 | xread(fd, magic.b32, sizeof(magic.b32[0])); |
207 | if (magic.b32[0] == XZ_MAGIC2) { | 203 | if (magic.b32[0] == XZ_MAGIC2) { |
208 | xstate->xformer = unpack_xz_stream; | 204 | xstate->xformer = unpack_xz_stream; |
@@ -226,16 +222,7 @@ static transformer_state_t *setup_transformer_on_fd(int fd, int fail_if_not_comp | |||
226 | // USE_FOR_NOMMU(xstate->xformer_prog = "cat";) | 222 | // USE_FOR_NOMMU(xstate->xformer_prog = "cat";) |
227 | /* fall through to seeking bck over bytes we read earlier */ | 223 | /* fall through to seeking bck over bytes we read earlier */ |
228 | 224 | ||
229 | USE_FOR_NOMMU(found_magic:) | 225 | found_magic: |
230 | /* NOMMU version of fork_transformer execs | ||
231 | * an external unzipper that wants | ||
232 | * file position at the start of the file. | ||
233 | */ | ||
234 | xlseek(fd, offset, SEEK_CUR); | ||
235 | |||
236 | USE_FOR_MMU(found_magic:) | ||
237 | /* In MMU case, if magic was found, seeking back is not necessary */ | ||
238 | |||
239 | return xstate; | 226 | return xstate; |
240 | } | 227 | } |
241 | 228 | ||
@@ -254,6 +241,12 @@ int FAST_FUNC setup_unzip_on_fd(int fd, int fail_if_not_compressed) | |||
254 | # if BB_MMU | 241 | # if BB_MMU |
255 | fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); | 242 | fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); |
256 | # else | 243 | # else |
244 | /* NOMMU version of fork_transformer execs | ||
245 | * an external unzipper that wants | ||
246 | * file position at the start of the file. | ||
247 | */ | ||
248 | xlseek(fd, - xstate->signature_skipped, SEEK_CUR); | ||
249 | xstate->signature_skipped = 0; | ||
257 | fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); | 250 | fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); |
258 | # endif | 251 | # endif |
259 | free(xstate); | 252 | free(xstate); |
@@ -300,6 +293,8 @@ int FAST_FUNC open_zipped(const char *fname, int fail_if_not_compressed) | |||
300 | # if BB_MMU | 293 | # if BB_MMU |
301 | fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); | 294 | fork_transformer_with_no_sig(xstate->src_fd, xstate->xformer); |
302 | # else | 295 | # else |
296 | xlseek(fd, - xstate->signature_skipped, SEEK_CUR); | ||
297 | xstate->signature_skipped = 0; | ||
303 | fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); | 298 | fork_transformer_with_sig(xstate->src_fd, xstate->xformer, xstate->xformer_prog); |
304 | # endif | 299 | # endif |
305 | } | 300 | } |
diff --git a/include/bb_archive.h b/include/bb_archive.h index 10969b567..2b9c5f04c 100644 --- a/include/bb_archive.h +++ b/include/bb_archive.h | |||
@@ -211,7 +211,7 @@ void dealloc_bunzip(bunzip_data *bd) FAST_FUNC; | |||
211 | 211 | ||
212 | /* Meaning and direction (input/output) of the fields are transformer-specific */ | 212 | /* Meaning and direction (input/output) of the fields are transformer-specific */ |
213 | typedef struct transformer_state_t { | 213 | typedef struct transformer_state_t { |
214 | smallint check_signature; /* most often referenced member */ | 214 | smallint signature_skipped; /* most often referenced member */ |
215 | 215 | ||
216 | IF_DESKTOP(long long) int FAST_FUNC (*xformer)(struct transformer_state_t *xstate); | 216 | IF_DESKTOP(long long) int FAST_FUNC (*xformer)(struct transformer_state_t *xstate); |
217 | USE_FOR_NOMMU(const char *xformer_prog;) | 217 | USE_FOR_NOMMU(const char *xformer_prog;) |
@@ -252,11 +252,11 @@ int bbunpack(char **argv, | |||
252 | void check_errors_in_children(int signo); | 252 | void check_errors_in_children(int signo); |
253 | #if BB_MMU | 253 | #if BB_MMU |
254 | void fork_transformer(int fd, | 254 | void fork_transformer(int fd, |
255 | int check_signature, | 255 | int signature_skipped, |
256 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate) | 256 | IF_DESKTOP(long long) int FAST_FUNC (*transformer)(transformer_state_t *xstate) |
257 | ) FAST_FUNC; | 257 | ) FAST_FUNC; |
258 | #define fork_transformer_with_sig(fd, transformer, transform_prog) fork_transformer((fd), 1, (transformer)) | 258 | #define fork_transformer_with_sig(fd, transformer, transform_prog) fork_transformer((fd), 0, (transformer)) |
259 | #define fork_transformer_with_no_sig(fd, transformer) fork_transformer((fd), 0, (transformer)) | 259 | #define fork_transformer_with_no_sig(fd, transformer) fork_transformer((fd), 1, (transformer)) |
260 | #else | 260 | #else |
261 | void fork_transformer(int fd, const char *transform_prog) FAST_FUNC; | 261 | void fork_transformer(int fd, const char *transform_prog) FAST_FUNC; |
262 | #define fork_transformer_with_sig(fd, transformer, transform_prog) fork_transformer((fd), (transform_prog)) | 262 | #define fork_transformer_with_sig(fd, transformer, transform_prog) fork_transformer((fd), (transform_prog)) |