diff options
author | Dan Fandrich <dan@coneharvesters.com> | 2010-06-17 21:39:44 -0700 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2010-06-18 13:32:39 +0200 |
commit | b76f18d331f865225f1702794e66e87818584f99 (patch) | |
tree | 62c935bc2db0fd5af12fae2e3e060924a900e484 /archival/unzip.c | |
parent | eafc6956f6fa86cb7d4bf488e96eeee34c551819 (diff) | |
download | busybox-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.c | 13 |
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! */ |
154 | static uint32_t find_cdf_offset(void) | 157 | static 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 | ||