Browse code

properly handle metadata for large files

git-svn: trunk@2650

Tomasz Kojm authored on 2007/01/31 00:35:59
Showing 4 changed files
... ...
@@ -1,3 +1,7 @@
1
+Tue Jan 30 16:31:37 CET 2007 (tk)
2
+---------------------------------
3
+  * libclamav/unrar/unrar.c: properly handle metadata for large files
4
+
1 5
 Mon Jan 29 16:17:53 CET 2007 (tk)
2 6
 ---------------------------------
3 7
   * libclamav/cab.c: improve format scoring
... ...
@@ -199,8 +199,8 @@ static int cli_unrar_checklimits(const cli_ctx *ctx, const rar_metadata_t *metad
199 199
 {
200 200
     if(ctx->limits) {
201 201
 	if(ctx->limits->maxratio && metadata->unpack_size && metadata->pack_size) {
202
-	    if((unsigned int) metadata->unpack_size / (unsigned int) metadata->pack_size >= ctx->limits->maxratio) {
203
-		cli_dbgmsg("RAR: Max ratio reached (normal: %u, compressed: %u, max: %ld)\n", metadata->unpack_size, metadata->pack_size, ctx->limits->maxratio);
202
+	    if(metadata->unpack_size / metadata->pack_size >= ctx->limits->maxratio) {
203
+		cli_dbgmsg("RAR: Max ratio reached (normal: %Lu, compressed: %Lu, max: %u)\n", metadata->unpack_size, metadata->pack_size, ctx->limits->maxratio);
204 204
 		if(BLOCKMAX) {
205 205
 		    *ctx->virname = "Oversized.RAR";
206 206
 		    return CL_VIRUS;
... ...
@@ -210,7 +210,7 @@ static int cli_unrar_checklimits(const cli_ctx *ctx, const rar_metadata_t *metad
210 210
 	}
211 211
 
212 212
 	if(ctx->limits->maxfilesize && (metadata->unpack_size > ctx->limits->maxfilesize)) {
213
-	    cli_dbgmsg("RAR: %s: Size exceeded (%u, max: %lu)\n", metadata->filename, metadata->unpack_size, ctx->limits->maxfilesize);
213
+	    cli_dbgmsg("RAR: %s: Size exceeded (%Lu, max: %lu)\n", metadata->filename, metadata->unpack_size, ctx->limits->maxfilesize);
214 214
 	    if(BLOCKMAX) {
215 215
 		*ctx->virname = "RAR.ExceededFileSize";
216 216
 		return CL_VIRUS;
... ...
@@ -219,7 +219,7 @@ static int cli_unrar_checklimits(const cli_ctx *ctx, const rar_metadata_t *metad
219 219
 	}
220 220
 
221 221
 	if(ctx->limits->maxfiles && (files > ctx->limits->maxfiles)) {
222
-	    cli_dbgmsg("RAR: Files limit reached (max: %d)\n", ctx->limits->maxfiles);
222
+	    cli_dbgmsg("RAR: Files limit reached (max: %u)\n", ctx->limits->maxfiles);
223 223
 	    if(BLOCKMAX) {
224 224
 		*ctx->virname = "RAR.ExceededFilesLimit";
225 225
 		return CL_VIRUS;
... ...
@@ -287,6 +287,18 @@ static void *read_header(int fd, header_type hdr_type)
287 287
 		file_hdr->unpack_size = rar_endian_convert_32(file_hdr->unpack_size);
288 288
 		file_hdr->file_crc = rar_endian_convert_32(file_hdr->file_crc);
289 289
 		file_hdr->name_size = rar_endian_convert_16(file_hdr->name_size);
290
+		if(file_hdr->flags & 0x100) {
291
+			if (cli_readn(fd, file_hdr + SIZEOF_NEWLHD, 8) != 8) {
292
+				free(file_hdr);
293
+				return NULL;
294
+			}
295
+			file_hdr->high_pack_size = rar_endian_convert_32(file_hdr->high_pack_size);
296
+			file_hdr->high_unpack_size = rar_endian_convert_32(file_hdr->high_unpack_size);
297
+		} else {
298
+			file_hdr->high_pack_size = 0;
299
+			file_hdr->high_unpack_size = 0;
300
+		}
301
+
290 302
 		return file_hdr;
291 303
 		}
292 304
 	case COMM_HEAD: {
... ...
@@ -1541,8 +1553,8 @@ int cli_unrar_extract_next_prepare(rar_state_t* state,const char* dirname)
1541 1541
 		if (!new_metadata) {
1542 1542
 		return CL_EMEM;
1543 1543
 		}
1544
-		new_metadata->pack_size = state->file_header->pack_size;
1545
-		new_metadata->unpack_size = state->file_header->unpack_size;
1544
+		new_metadata->pack_size = state->file_header->high_pack_size * 0x100000000 + state->file_header->pack_size;
1545
+		new_metadata->unpack_size = state->file_header->high_unpack_size * 0x100000000 + state->file_header->unpack_size;
1546 1546
 		new_metadata->crc = state->file_header->file_crc;
1547 1547
 		new_metadata->method = state->file_header->method;
1548 1548
 		new_metadata->filename = strdup(state->file_header->filename);
... ...
@@ -47,8 +47,8 @@ struct unpack_data_tag;
47 47
 
48 48
 typedef struct rar_metadata_tag
49 49
 {
50
-	uint32_t pack_size;
51
-	uint32_t unpack_size;
50
+	uint64_t pack_size;
51
+	uint64_t unpack_size;
52 52
 	uint32_t crc;
53 53
 	unsigned int encrypted;
54 54
 	uint8_t method;
... ...
@@ -143,6 +143,8 @@ typedef struct file_header_tag
143 143
 	uint8_t method __attribute__ ((packed));
144 144
 	uint16_t name_size __attribute__ ((packed));
145 145
 	uint32_t file_attr __attribute__ ((packed));
146
+	uint32_t high_pack_size __attribute__ ((packed));   /* optional */
147
+	uint32_t high_unpack_size __attribute__ ((packed)); /* optional */
146 148
 	unsigned char *filename __attribute__ ((packed));
147 149
 	off_t start_offset __attribute__ ((packed));
148 150
 	off_t next_offset __attribute__ ((packed));