88
99typedef struct {
1010 char * filename ;
11- char * symlink ;
1211 uint8_t * data ;
1312 size_t data_size ;
1413} FileData ;
@@ -42,6 +41,7 @@ ExtractedArchive* extract_archive(uint8_t* inputData, size_t inputSize ) {
4241 FileData * files = NULL ;
4342 size_t files_count = 0 ;
4443 const char * error_message ;
44+ bool hasSymLinks = false;
4545
4646 ExtractedArchive * result = (ExtractedArchive * )malloc (sizeof (ExtractedArchive ));
4747 if (!result ) {
@@ -66,19 +66,12 @@ ExtractedArchive* extract_archive(uint8_t* inputData, size_t inputSize ) {
6666 const char * filename = archive_entry_pathname (entry );
6767 size_t entrySize = archive_entry_size (entry );
6868
69+ // Ignore symbolic links for now
6970 if (archive_entry_filetype (entry ) == AE_IFLNK ) {
70- // It's a symbolic link
71- const char * target = archive_entry_symlink (entry );
72-
73- files [files_count ].filename = strdup (filename );
74- files [files_count ].symlink = strdup (target );
75-
76- files_count ++ ;
77-
71+ hasSymLinks = true;
7872 continue ;
7973 }
8074
81-
8275 if (files_count + 1 > files_struct_length ) {
8376 files_struct_length *= 2 ; // double the length
8477 FileData * oldfiles = files ;
@@ -90,9 +83,8 @@ ExtractedArchive* extract_archive(uint8_t* inputData, size_t inputSize ) {
9083 return error_handler (result , error_message , archive );
9184 }
9285 }
86+
9387 files [files_count ].filename = strdup (filename );
94- free (files [files_count ].symlink );
95- files [files_count ].symlink = NULL ;
9688 files [files_count ].data = malloc (entrySize );
9789 files [files_count ].data_size = entrySize ;
9890
@@ -122,6 +114,77 @@ ExtractedArchive* extract_archive(uint8_t* inputData, size_t inputSize ) {
122114 files_count ++ ;
123115 }
124116
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+
125188 archive_read_free (archive );
126189 result -> files = files ;
127190 result -> fileCount = files_count ;
@@ -211,7 +274,6 @@ ExtractedArchive* decompression(uint8_t* inputData, size_t inputSize) {
211274 if (!filename ) filename = "decompression" ;
212275
213276 files [files_count ].filename = strdup (filename );
214- files [files_count ].symlink = strdup ("" );
215277 files [files_count ].data = NULL ;
216278 files [files_count ].data_size = 0 ;
217279
@@ -273,7 +335,6 @@ void free_extracted_archive(ExtractedArchive* archive) {
273335 }
274336 for (size_t i = 0 ; i < archive -> fileCount ; i ++ ) {
275337 free (archive -> files [i ].filename );
276- free (archive -> files [i ].symlink );
277338 free (archive -> files [i ].data );
278339 }
279340 free (archive -> files );
0 commit comments