Browse code

bound memory usage; cleanups.

git-svn-id: file:///var/lib/svn/clamav-devel/trunk/clamav-devel@687 77e5149b-7576-45b1-b177-96237e5ba77b

Trog authored on 2004/07/22 20:16:03
Showing 2 changed files
... ...
@@ -1,3 +1,7 @@
1
+Thu Jul 22 12:13:56 BST 2004 (trog)
2
+-----------------------------------
3
+ * libclamav/chmunpack.c: bound memory usage; cleanups.
4
+
1 5
 Thu Jul 22 10:17:01 BST 2004 (njh)
2 6
 ----------------------------------
3 7
   * clamav-milter:	Use gethostbyname_r when available
... ...
@@ -48,6 +48,8 @@
48 48
 #define FALSE (0)
49 49
 #define TRUE (1)
50 50
 
51
+#define MIN(a,b) ((a < b) ? a : b)
52
+
51 53
 #ifndef HAVE_ATTRIB_PACKED
52 54
 #define __attribute__(x)
53 55
 #endif
... ...
@@ -200,6 +202,28 @@ int chm_read_data(int fd, unsigned char *dest, off_t offset, uint32_t len,
200 200
 	return TRUE;
201 201
 }
202 202
 
203
+int chm_copy_file_data(int ifd, int ofd, uint64_t len)
204
+{
205
+	unsigned char data[8192];
206
+	uint64_t count, rem;
207
+	unsigned int todo;
208
+	
209
+	rem = len;
210
+
211
+	while (rem > 0) {
212
+		todo = MIN(8192, rem);
213
+		count = cli_readn(ifd, data, todo);
214
+		if (count != todo) {
215
+			return len-rem;
216
+		}
217
+		if (cli_writen(ofd, data, count) != count) {
218
+			return len-rem-count;
219
+		}
220
+		rem -= count;
221
+	}
222
+	return len;
223
+}
224
+
203 225
 static void free_file_list(file_list_t *file_l)
204 226
 {
205 227
 	file_list_t *next;
... ...
@@ -433,7 +457,7 @@ static int read_chunk_entries(unsigned char *chunk, uint32_t chunk_len,
433 433
 					file_list_t *file_l, file_list_t *sys_file_l)
434 434
 {
435 435
 	unsigned char *current, *end;
436
-	uint64_t length, offset, section, name_len;
436
+	uint64_t name_len;
437 437
 	file_list_t *file_e;
438 438
 
439 439
 	end = chunk + chunk_len;
... ...
@@ -487,6 +511,7 @@ static int read_chunk_entries(unsigned char *chunk, uint32_t chunk_len,
487 487
 					file_e->section, file_e->offset,
488 488
 					file_e->length, file_e->name);
489 489
 	}
490
+	return TRUE;
490 491
 }
491 492
 
492 493
 static void print_chunk(chunk_header_t *chunk)
... ...
@@ -797,7 +822,7 @@ abort:
797 797
 	return NULL;
798 798
 }
799 799
 
800
-/* ******************************************************************
800
+/* *****************************************************************/
801 801
 /* This section interfaces to the mspack files. As such, this is a */
802 802
 /* little bit dirty compared to my usual code */
803 803
 
... ...
@@ -822,16 +847,20 @@ static int chm_decompress_stream(int fd, const char *dirname, itsf_header_t *its
822 822
 	lzx_reset_table_t *lzx_reset_table=NULL;
823 823
 	lzx_control_t *lzx_control=NULL;
824 824
 	int window_bits, length, ofd, retval=FALSE;
825
-	uint64_t offset, com_offset;
825
+	uint64_t com_offset;
826 826
 	struct mspack_file_p mf_in, mf_out;
827 827
 	struct lzxd_stream * stream;
828
-	unsigned char *data, filename[1024];
828
+	unsigned char filename[1024];
829 829
 	
830
-	mf_in.fh = fdopen(fd, "r");
830
+	mf_in.desc = dup(fd);
831
+	if (mf_in.desc < 0) {
832
+		return FALSE;
833
+	}
834
+	mf_in.fh = fdopen(mf_in.desc, "r");
831 835
 	if (!mf_in.fh) {
836
+		close(mf_in.desc);
832 837
 		return FALSE;
833 838
 	}
834
-	mf_in.desc = fd;
835 839
 	mf_in.name = strdup("input");
836 840
 	
837 841
 	snprintf(filename, 1024, "%s/clamav-unchm.bin", dirname);
... ...
@@ -943,27 +972,21 @@ static int chm_decompress_stream(int fd, const char *dirname, itsf_header_t *its
943 943
 			entry = entry->next;
944 944
 			continue;
945 945
 		}
946
-		data = (unsigned char *) cli_malloc(entry->length);
947
-		if (!data) {
948
-			goto abort;
949
-		}
946
+		
950 947
 		snprintf(filename, 1024, "%s/%llu.chm", dirname, entry->offset);
951 948
 		ofd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, S_IRWXU);
952 949
 		if (ofd < 0) {
953
-			free(data);
954 950
 			entry = entry->next;
955 951
 			continue;
956 952
 		}
957
-		if ((length=cli_readn(mf_out.desc, data, entry->length)) != entry->length) {
958
-			cli_dbgmsg("read %d of %d\n", length, entry->length);
953
+		if ((length=chm_copy_file_data(mf_out.desc, ofd, entry->length)) != entry->length) {
954
+			cli_dbgmsg("copied %d of %d\n", length, entry->length);
959 955
 		}
960
-		cli_writen(ofd, data, length);
961
-		close(ofd);
962
-		free(data);
963 956
 		
957
+		close(ofd);		
964 958
 		entry = entry->next;
965 959
 	}
966
-		
960
+	close(mf_out.desc);
967 961
 	retval = TRUE;
968 962
 	
969 963
 abort:
... ...
@@ -982,7 +1005,6 @@ abort:
982 982
 	if (mf_out.fh) {
983 983
 		fclose(mf_out.fh);
984 984
 	}
985
-	close(mf_out.desc);
986 985
 	return retval;
987 986
 }
988 987
 
... ...
@@ -992,13 +1014,12 @@ int chm_unpack(int fd, const char *dirname)
992 992
 {
993 993
 	int retval=FALSE;
994 994
 	unsigned char *m_area=NULL;
995
-	off_t m_length, offset;
995
+	off_t m_length=0, offset;
996 996
 	file_list_t *file_l, *sys_file_l;
997 997
 	struct stat statbuf;
998 998
 	itsf_header_t itsf_hdr;
999 999
 	itsp_header_t itsp_hdr;
1000 1000
 	uint32_t num_chunks;
1001
-	chunk_header_t *chunk;
1002 1001
 
1003 1002
 	/* These two lists contain the list of files and system files in
1004 1003
 	the archive. The first entry in the list is an empty entry */