Browse code

improve handling of archives with unusual headers

git-svn: trunk@2593

Tomasz Kojm authored on 2007/01/07 09:25:48
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Sun Jan  7 01:24:21 CET 2007 (tk)
2
+---------------------------------
3
+  * libclamav/unzip.c: improve handling of archives with unusual headers
4
+
1 5
 Sat Jan  6 17:45:49 CET 2007 (tk)
2 6
 ---------------------------------
3 7
   * clamd: s/DetectPhishing/PhishingSignatures
... ...
@@ -168,14 +168,15 @@ int __zip_find_disk_trailer(int fd, off_t filesize, struct zip_disk_trailer *tra
168 168
 int __zip_parse_root_directory(int fd, struct zip_disk_trailer *trailer, zip_dir_hdr **hdr_return, off_t start)
169 169
 {
170 170
 	struct zip_root_dirent dirent, *d;
171
-	zip_dir_hdr *hdr, *hdr0;
171
+	zip_dir_hdr *hdr, *hdr0, *prev_hdr;
172 172
 	uint16_t *p_reclen = NULL, entries;
173 173
 	uint32_t offset;
174 174
 	struct stat sb;
175 175
 	uint16_t u_entries  = EC16(trailer->z_entries);   
176 176
 	uint32_t u_rootsize = EC32(trailer->z_rootsize);  
177 177
 	uint32_t u_rootseek = EC32(trailer->z_rootseek) + start;
178
-        uint16_t u_extras, u_comment, u_namlen, u_flags;
178
+	uint16_t u_extras, u_comment, u_namlen, u_flags;
179
+	uint8_t clone_entry;
179 180
 	char *pt;
180 181
 
181 182
 
... ...
@@ -196,6 +197,8 @@ int __zip_parse_root_directory(int fd, struct zip_disk_trailer *trailer, zip_dir
196 196
     hdr = hdr0;
197 197
 
198 198
     for(entries = u_entries, offset = 0; entries > 0; entries--) {
199
+	clone_entry = 0;
200
+
199 201
 	if(lseek(fd, u_rootseek + offset, SEEK_SET) < 0) {
200 202
 	    free(hdr0);
201 203
 	    cli_errmsg("Unzip: __zip_parse_root_directory: Can't lseek descriptor %d\n", fd);
... ...
@@ -244,6 +247,7 @@ int __zip_parse_root_directory(int fd, struct zip_disk_trailer *trailer, zip_dir
244 244
 	    cli_dbgmsg("Unzip: __zip_parse_root_directory: File claims to be deflated but csize == usize\n");
245 245
 	    cli_dbgmsg("Unzip: __zip_parse_root_directory: Assuming method 'stored'\n");
246 246
 	    hdr->d_compr = 0;
247
+	    clone_entry = 1;
247 248
 	}
248 249
 
249 250
 	hdr->d_flags = u_flags;
... ...
@@ -274,7 +278,20 @@ int __zip_parse_root_directory(int fd, struct zip_disk_trailer *trailer, zip_dir
274 274
 	hdr->d_reclen = (uint16_t) (pt - (char *) hdr);
275 275
 	p_reclen = &hdr->d_reclen;
276 276
 
277
+	prev_hdr = hdr;
277 278
 	hdr = (zip_dir_hdr *) ((char *) hdr + hdr->d_reclen);
279
+
280
+	if(clone_entry) {
281
+	    hdr0 = (zip_dir_hdr *) cli_realloc(hdr0, u_rootsize + *p_reclen);
282
+	    if(!hdr0)
283
+		return CL_EMEM;
284
+	    memcpy((zip_dir_hdr *) hdr, (zip_dir_hdr *) prev_hdr, *p_reclen);
285
+	    hdr->d_compr = 8;
286
+	    if(u_namlen)
287
+		hdr->d_name[strlen(hdr->d_name) - 1]++;
288
+	    p_reclen = &hdr->d_reclen;
289
+	    hdr = (zip_dir_hdr *) ((char *) hdr + hdr->d_reclen);
290
+	}
278 291
     }
279 292
 
280 293
     if(p_reclen) {