aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2016-06-20 11:06:42 +0200
committerDenys Vlasenko <vda.linux@googlemail.com>2016-06-20 11:06:42 +0200
commit984b0a613aaf1cdf48c2e2af08c8466a7bad8307 (patch)
tree57b512d3843221b92da936b46abd238d1a036a94
parentecf25cb5bce27ca5820e2895d8458f38c406d105 (diff)
downloadbusybox-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.c2
-rw-r--r--archival/libarchive/decompress_gunzip.c4
-rw-r--r--archival/libarchive/decompress_unxz.c2
-rw-r--r--archival/libarchive/open_transformer.c35
-rw-r--r--include/bb_archive.h8
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
14int FAST_FUNC check_signature16(transformer_state_t *xstate, unsigned magic16) 14int 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
104void FAST_FUNC fork_transformer(int fd, 101void 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 */
213typedef struct transformer_state_t { 213typedef 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,
252void check_errors_in_children(int signo); 252void check_errors_in_children(int signo);
253#if BB_MMU 253#if BB_MMU
254void fork_transformer(int fd, 254void 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
261void fork_transformer(int fd, const char *transform_prog) FAST_FUNC; 261void 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))