@@ -141,28 +141,90 @@ fileprivate extension InjectorV3 {
141
141
142
142
var hasAnyDylib = false
143
143
var tarReader = TarReader ( fileHandle: tarHandle)
144
+ var processedBundles = Set < String > ( )
145
+ var bundleContents : [ String : [ ( info: TarEntryInfo , data: Data ? ) ] ] = [ : ]
144
146
while let entry = try tarReader. read ( ) {
145
- guard entry. info. type == . regular,
146
- entry. info. name. hasSuffix ( " .dylib " ) ,
147
- let entryData = entry. data
148
- else {
149
- continue
150
- }
151
-
152
- let dylibName = URL ( fileURLWithPath: entry. info. name, relativeTo: targetURL) . lastPathComponent
153
- guard !dylibName. hasPrefix ( " . " ) else {
154
- continue
155
- }
147
+ if entry. info. type == . regular && entry. info. name. hasSuffix ( " .dylib " ) {
148
+ guard let entryData = entry. data else {
149
+ continue
150
+ }
151
+ let dylibName = URL ( fileURLWithPath: entry. info. name, relativeTo: targetURL) . lastPathComponent
152
+ guard !dylibName. hasPrefix ( " . " ) else {
153
+ continue
154
+ }
156
155
157
- DDLogWarn ( " Found dylib \( entry. info. name) name \( dylibName) " , ddlog: logger)
156
+ DDLogWarn ( " Found dylib \( entry. info. name) name \( dylibName) " , ddlog: logger)
157
+
158
+ let entryURL = targetURL. appendingPathComponent ( dylibName)
159
+ try entryData. write ( to: entryURL)
160
+ hasAnyDylib = true
161
+ } else if entry. info. type == . directory && entry. info. name. hasSuffix ( " .bundle " ) {
162
+ // Extract bundle name
163
+ let bundleName = URL ( fileURLWithPath: entry. info. name) . lastPathComponent
164
+ // Avoid processing duplicate or nested bundles
165
+ guard !processedBundles. contains ( bundleName) else {
166
+ continue
167
+ }
168
+ // Track that we're processing this bundle
169
+ processedBundles. insert ( bundleName)
170
+ // Store bundle entries for later processing
171
+ bundleContents [ entry. info. name] = [ ]
158
172
159
- let entryURL = targetURL. appendingPathComponent ( dylibName)
160
- try entryData. write ( to: entryURL)
161
- hasAnyDylib = true
173
+ DDLogWarn ( " Found bundle \( entry. info. name) name \( bundleName) " , ddlog: logger)
174
+ } else {
175
+ // Collect contents for all bundles
176
+ for (bundlePath, _) in bundleContents {
177
+ if entry. info. name. starts ( with: bundlePath + " / " ) {
178
+ bundleContents [ bundlePath] ? . append ( ( entry. info, entry. data) )
179
+ }
180
+ }
181
+ }
162
182
}
163
183
164
184
if !hasAnyDylib {
165
185
throw Error . generic ( NSLocalizedString ( " No dylib found in the Debian package. " , comment: " " ) )
166
186
}
187
+ let fileManager = FileManager . default
188
+ // Process collected bundle contents
189
+ for (bundlePath, contents) in bundleContents {
190
+ let bundleName = URL ( fileURLWithPath: bundlePath) . lastPathComponent
191
+
192
+ DDLogInfo ( " Preparing to copy bundle \( bundlePath) " , ddlog: logger)
193
+
194
+ // Destination for the bundle
195
+ let destinationBundleURL = targetURL. appendingPathComponent ( bundleName)
196
+ // Remove existing bundle if it exists
197
+ if fileManager. fileExists ( atPath: destinationBundleURL. path) {
198
+ try fileManager. removeItem ( at: destinationBundleURL)
199
+ }
200
+ // Create destination directory for the bundle
201
+ try fileManager. createDirectory ( at: destinationBundleURL, withIntermediateDirectories: true )
202
+
203
+ // Copy bundle contents
204
+ for entry in contents {
205
+ // Get relative path within the bundle
206
+ let relativePath = String ( entry. info. name. dropFirst ( bundlePath. count + 1 ) )
207
+ let destinationPath = destinationBundleURL. appendingPathComponent ( relativePath)
208
+ // Handle different entry types
209
+ switch entry. info. type {
210
+ case . directory:
211
+ // Create subdirectories
212
+ try fileManager. createDirectory ( at: destinationPath, withIntermediateDirectories: true )
213
+ case . regular:
214
+ // Ensure destination directory exists
215
+ try fileManager. createDirectory ( at: destinationPath. deletingLastPathComponent ( ) , withIntermediateDirectories: true )
216
+ // Write file contents
217
+ guard let fileData = entry. data else {
218
+ DDLogWarn ( " Unable to read data for \( entry. info. name) " , ddlog: logger)
219
+ continue
220
+ }
221
+ try fileData. write ( to: destinationPath)
222
+ default :
223
+ continue
224
+ }
225
+ }
226
+
227
+ DDLogInfo ( " Successfully copied bundle \( bundleName) " , ddlog: logger)
228
+ }
167
229
}
168
230
}
0 commit comments