55#include <archive.h>
66#include <archive_entry.h>
77#include <emscripten.h>
8+ #include <sys/time.h>
89
910typedef struct {
1011 char * filename ;
@@ -19,6 +20,13 @@ typedef struct {
1920 char error_message [256 ];
2021} ExtractedArchive ;
2122
23+
24+ double get_time () {
25+ struct timeval tv ;
26+ gettimeofday (& tv , NULL );
27+ return (tv .tv_sec ) + tv .tv_usec / 1000000.0 ;
28+ }
29+
2230ExtractedArchive * error_handler (ExtractedArchive * result , const char * error_message , struct archive * archive ) {
2331
2432 if (!result || !archive ) {
@@ -157,9 +165,15 @@ ExtractedArchive* decompression(uint8_t* input_data, size_t input_size) {
157165 size_t files_struct_length = 1 ;
158166 size_t compression_ratio = 10 ;
159167 size_t estimated_decompressed_size = input_size * compression_ratio ;
160- const size_t buffsize = estimated_decompressed_size ;
168+
169+ /* 64KB, archive_read_data can do realloc too during reading data,
170+ so data chunks size should be defined carefully. There is memory leaks with 4MB data chunck size
171+ */
172+ const size_t buffsize = 65536 ;
161173 char * buff = (char * )malloc (buffsize );
162174
175+ double start_time , end_time ;
176+
163177 if (!buff ) {
164178 printf ("Failed to allocate memory for decompression buffer\n" );
165179 return NULL ;
@@ -195,15 +209,19 @@ ExtractedArchive* decompression(uint8_t* input_data, size_t input_size) {
195209 archive = archive_read_new ();
196210 archive_read_support_filter_all (archive );
197211 archive_read_support_format_raw (archive );
198-
212+
213+ /* Putting buffer size allows libarchive to read a file by data chunks.
214+ This reduces memory leaks on libarchive side
215+ */
216+
199217 if (archive_read_open_filename (archive , temp_file_name , buffsize ) != ARCHIVE_OK ) {
200218 unlink (temp_file_name );
201219 free (temp_file_name );
202220 free (files );
203221 free (buff );
204222 return error_handler (result , archive_error_string (archive ), archive );
205223 }
206-
224+
207225 while (archive_read_next_header (archive , & entry ) == ARCHIVE_OK ) {
208226 if (files_count + 1 > files_struct_length ) {
209227 files_struct_length *= 2 ; // double the length
@@ -286,16 +304,11 @@ ExtractedArchive* decompression(uint8_t* input_data, size_t input_size) {
286304 files [files_count ].data = new_data ;
287305 estimated_decompressed_size = new_size ;
288306
289- } else if (sum > 0 && sum < estimated_decompressed_size ) {
290- memcpy (files [files_count ].data + total_size , buff , ret );
291- total_size += ret ;
292- break ;
293307 }
294308
295309 memcpy (files [files_count ].data + total_size , buff , ret );
296310 total_size += ret ;
297311 }
298-
299312
300313 files [files_count ].data_size = total_size ;
301314 files_count ++ ;
0 commit comments