@@ -41,6 +41,7 @@ ExtractedArchive* extract_archive(uint8_t* inputData, size_t inputSize ) {
4141 FileData * files = NULL ;
4242 size_t files_count = 0 ;
4343 const char * error_message ;
44+ bool hasSymLinks = false;
4445
4546 ExtractedArchive * result = (ExtractedArchive * )malloc (sizeof (ExtractedArchive ));
4647 if (!result ) {
@@ -57,13 +58,20 @@ ExtractedArchive* extract_archive(uint8_t* inputData, size_t inputSize ) {
5758 archive_read_support_format_all (archive );
5859
5960 if (archive_read_open_memory (archive , inputData , inputSize ) != ARCHIVE_OK ) {
60- return error_handler (result ,archive_error_string (archive ), archive );
61+ return error_handler (result ,archive_error_string (archive ), archive );
6162 }
6263 files = malloc (sizeof (FileData ) * files_struct_length );
6364
6465 while (archive_read_next_header (archive , & entry ) == ARCHIVE_OK ) {
6566 const char * filename = archive_entry_pathname (entry );
6667 size_t entrySize = archive_entry_size (entry );
68+
69+ // Ignore symbolic links for now
70+ if (archive_entry_filetype (entry ) == AE_IFLNK ) {
71+ hasSymLinks = true;
72+ continue ;
73+ }
74+
6775 if (files_count + 1 > files_struct_length ) {
6876 files_struct_length *= 2 ; // double the length
6977 FileData * oldfiles = files ;
@@ -73,8 +81,9 @@ ExtractedArchive* extract_archive(uint8_t* inputData, size_t inputSize ) {
7381 result -> files = oldfiles ; // otherwise memory is lost, alternatively also everything can be freed.
7482 error_message = "Memory allocation error for file data." ;
7583 return error_handler (result , error_message , archive );
76- }
84+ }
7785 }
86+
7887 files [files_count ].filename = strdup (filename );
7988 files [files_count ].data = malloc (entrySize );
8089 files [files_count ].data_size = entrySize ;
@@ -105,6 +114,77 @@ ExtractedArchive* extract_archive(uint8_t* inputData, size_t inputSize ) {
105114 files_count ++ ;
106115 }
107116
117+ // Resolve symlinks
118+ if (hasSymLinks ) {
119+ // Rewind and reopen the archive to iterate over symlinks
120+ archive_read_free (archive );
121+ archive = archive_read_new ();
122+ archive_read_support_filter_all (archive );
123+ archive_read_support_format_all (archive );
124+
125+ if (archive_read_open_memory (archive , inputData , inputSize ) != ARCHIVE_OK ) {
126+ return error_handler (result , archive_error_string (archive ), archive );
127+ }
128+
129+ struct archive_entry * symlink_entry ;
130+ while (archive_read_next_header (archive , & symlink_entry ) == ARCHIVE_OK ) {
131+ // Process only symlinks this time
132+ if (archive_entry_filetype (symlink_entry ) != AE_IFLNK ) {
133+ continue ;
134+ }
135+
136+ const char * linkname = archive_entry_pathname (symlink_entry );
137+ const char * target = archive_entry_symlink (symlink_entry );
138+
139+ // Target not found
140+ if (!target ) {
141+ continue ;
142+ }
143+
144+ // Find the target file in the already populated files[]
145+ size_t target_index = (size_t )-1 ;
146+ for (size_t i = 0 ; i < files_count ; i ++ ) {
147+ if (strcmp (files [i ].filename , target ) == 0 ) {
148+ target_index = i ;
149+ break ;
150+ }
151+ }
152+
153+ // Target not found in the processed files
154+ if (target_index == (size_t )-1 || !files [target_index ].data ) {
155+ continue ;
156+ }
157+
158+ // Add the symlink entry
159+ if (files_count + 1 > files_struct_length ) {
160+ files_struct_length *= 2 ;
161+ FileData * oldfiles = files ;
162+ files = realloc (files , sizeof (FileData ) * files_struct_length );
163+ if (!files ) {
164+ result -> fileCount = files_count ;
165+ result -> files = oldfiles ;
166+ error_message = "Memory allocation error for symlink data." ;
167+ return error_handler (result , error_message , archive );
168+ }
169+ }
170+
171+ files [files_count ].filename = strdup (linkname );
172+ files [files_count ].data_size = files [target_index ].data_size ;
173+ files [files_count ].data = malloc (files [target_index ].data_size );
174+ if (!files [files_count ].data ) {
175+ free (files [files_count ].filename );
176+ files [files_count ].filename = NULL ;
177+ result -> fileCount = files_count ;
178+ result -> files = files ;
179+ error_message = "Memory allocation error for symlink target data." ;
180+ return error_handler (result , error_message , archive );
181+ }
182+ memcpy (files [files_count ].data , files [target_index ].data , files [target_index ].data_size );
183+
184+ files_count ++ ;
185+ }
186+ }
187+
108188 archive_read_free (archive );
109189 result -> files = files ;
110190 result -> fileCount = files_count ;
@@ -150,7 +230,7 @@ ExtractedArchive* decompression(uint8_t* inputData, size_t inputSize) {
150230
151231 const size_t buffsize = 64 * 1024 ;
152232 char buff [buffsize ];
153- size_t total_size = 0 ;
233+ size_t total_size = 0 ;
154234 const char * error_message ;
155235
156236 FileData * files = malloc (sizeof (FileData ) * (files_count + 1 ));
@@ -159,7 +239,7 @@ ExtractedArchive* decompression(uint8_t* inputData, size_t inputSize) {
159239 printf ("Failed to allocate memory for files array\n" );
160240 return NULL ;
161241 }
162-
242+
163243 ExtractedArchive * result = (ExtractedArchive * )malloc (sizeof (ExtractedArchive ));
164244 if (!result ) {
165245 free (files );
@@ -259,4 +339,4 @@ void free_extracted_archive(ExtractedArchive* archive) {
259339 }
260340 free (archive -> files );
261341 free (archive );
262- }
342+ }
0 commit comments