Commit 671705d
Fix intermittent CoreServices XPC crash in RCTBlobManager blob name derivation (#58172)
Summary:
### The crash
`-[NSURLResponse suggestedFilename]` derives a filename from the response's MIME type. Under the hood, that call makes a CoreServices/UTType **XPC round-trip**, and that XPC call crashes intermittently when invoked off the main thread (`NSXPCEncoder` / `objc_msgSend` frames).
### Why it fires on every request
`RCTBlobManager.handleNetworkingResponse:` calls `suggestedFilename` on the networking / TurboModule queue for every response it converts to a blob. Since `whatwg-fetch` reads **every** response body as a blob, the fragile call runs for every `fetch()` an app makes. Even a very low per-call crash rate becomes a steady stream of native crashes at scale.
We hit this in production at Phantom (millions of iOS users). Crash stacks consistently point into the UTType XPC machinery under `suggestedFilename`, always on the networking queue.
### The fix
Derive the blob's `name` from the URL's last path component instead. No XPC involved.
```objc
// before
@"name" : RCTNullIfNil([response suggestedFilename]),
// after
@"name" : RCTNullIfNil(response.URL.lastPathComponent),
```
**Tradeoff:** filenames from a `Content-Disposition` header (or a MIME-derived extension) are no longer used. A response blob's `name` is rarely consumed; it only feeds `Blob` / `File.name` for response bodies. If you'd prefer to keep `Content-Disposition` support, parsing that header directly here would also avoid the XPC call. Happy to iterate.
Related: the same XPC fragility on the **upload** path was reported in #35096.
## Changelog:
[IOS] [FIXED] - Fix intermittent native crash (CoreServices/UTType XPC) in RCTBlobManager when deriving blob names for network responses
Pull Request resolved: #58172
Test Plan:
- This exact change has run in production at Phantom since May 2026 (applied as a patch). The crash class disappeared and stayed gone.
- Fetch/blob flows (file and image downloads, uploads, WebSocket blobs) are covered by our device-farm e2e suites and are green with this change.
- `name` is still populated from the URL path, and is empty when the URL has no path component, which matches one of `suggestedFilename`'s own fallback tiers.
Reviewed By: javache
Differential Revision: D117876442
Pulled By: christophpurrer
fbshipit-source-id: 4505e4409e39595fd9fd3372dc93fc0fc39b5ae21 parent ea291d7 commit 671705d
1 file changed
Lines changed: 6 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
297 | 297 | | |
298 | 298 | | |
299 | 299 | | |
| 300 | + | |
| 301 | + | |
| 302 | + | |
| 303 | + | |
| 304 | + | |
300 | 305 | | |
301 | 306 | | |
302 | 307 | | |
303 | 308 | | |
304 | | - | |
| 309 | + | |
305 | 310 | | |
306 | 311 | | |
307 | 312 | | |
| |||
0 commit comments