aboutsummaryrefslogtreecommitdiff
path: root/archival/unzip.c
diff options
context:
space:
mode:
authorDan Fandrich <dan@coneharvesters.com>2010-06-17 21:39:44 -0700
committerDenys Vlasenko <vda.linux@googlemail.com>2010-06-18 13:32:39 +0200
commitb76f18d331f865225f1702794e66e87818584f99 (patch)
tree62c935bc2db0fd5af12fae2e3e060924a900e484 /archival/unzip.c
parenteafc6956f6fa86cb7d4bf488e96eeee34c551819 (diff)
downloadbusybox-w32-b76f18d331f865225f1702794e66e87818584f99.tar.gz
busybox-w32-b76f18d331f865225f1702794e66e87818584f99.tar.bz2
busybox-w32-b76f18d331f865225f1702794e66e87818584f99.zip
Improve unzip's handling of stream ZIP files
Search harder for the ZIP magic numbers at the end of a file by checking 16 KiB from the end instead of just 1 KiB. ZIP files with long comments (such as certain cryptographically signed files) or those sitting in a wrapper could have more than 1 KiB of data after the magic numbers, so they couldn't be read. Signed-off-by: Dan Fandrich <dan@coneharvesters.com> Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'archival/unzip.c')
-rw-r--r--archival/unzip.c13
1 files changed, 9 insertions, 4 deletions
diff --git a/archival/unzip.c b/archival/unzip.c
index 1d3291ab8..84081c021 100644
--- a/archival/unzip.c
+++ b/archival/unzip.c
@@ -150,23 +150,26 @@ enum { zip_fd = 3 };
150 150
151 151
152#if ENABLE_DESKTOP 152#if ENABLE_DESKTOP
153
154#define PEEK_FROM_END 16384
155
153/* NB: does not preserve file position! */ 156/* NB: does not preserve file position! */
154static uint32_t find_cdf_offset(void) 157static uint32_t find_cdf_offset(void)
155{ 158{
156 unsigned char buf[1024];
157 cde_header_t cde_header; 159 cde_header_t cde_header;
158 unsigned char *p; 160 unsigned char *p;
159 off_t end; 161 off_t end;
162 unsigned char *buf = xzalloc(PEEK_FROM_END);
160 163
161 end = xlseek(zip_fd, 0, SEEK_END); 164 end = xlseek(zip_fd, 0, SEEK_END);
162 end -= 1024; 165 end -= PEEK_FROM_END;
163 if (end < 0) 166 if (end < 0)
164 end = 0; 167 end = 0;
165 xlseek(zip_fd, end, SEEK_SET); 168 xlseek(zip_fd, end, SEEK_SET);
166 full_read(zip_fd, buf, 1024); 169 full_read(zip_fd, buf, PEEK_FROM_END);
167 170
168 p = buf; 171 p = buf;
169 while (p <= buf + 1024 - CDE_HEADER_LEN - 4) { 172 while (p <= buf + PEEK_FROM_END - CDE_HEADER_LEN - 4) {
170 if (*p != 'P') { 173 if (*p != 'P') {
171 p++; 174 p++;
172 continue; 175 continue;
@@ -180,8 +183,10 @@ static uint32_t find_cdf_offset(void)
180 /* we found CDE! */ 183 /* we found CDE! */
181 memcpy(cde_header.raw, p + 1, CDE_HEADER_LEN); 184 memcpy(cde_header.raw, p + 1, CDE_HEADER_LEN);
182 FIX_ENDIANNESS_CDE(cde_header); 185 FIX_ENDIANNESS_CDE(cde_header);
186 free(buf);
183 return cde_header.formatted.cdf_offset; 187 return cde_header.formatted.cdf_offset;
184 } 188 }
189 //free(buf);
185 bb_error_msg_and_die("can't find file table"); 190 bb_error_msg_and_die("can't find file table");
186}; 191};
187 192