Description
Description
Expected to happen
Calling RemoteConfig.addOnConfigUpdateListener(remoteConfigUpdateCompletion:)
should set up a listener for realtime config updates without crashing the app, regardless of network conditions.
Actual outcome
💥 We see intermittent crashes in Crashlytics where -[RCNConfigRealtime URLSession:dataTask:didReceiveData:]
attempted to construct a substring from an opening brace {
through to a closing one }
, expecting that they unconditionally occur in that order in the piece of NSData
returned by NSURLSession
, but they didn't.
The precise crash is an uncaught Obj-C exception CFString cannot be created from a negative number of bytes
thrown from the call to -[NSString substringWithRange:]
at RCNConfigRealtime.m:583
. The crash would be avoided by adding the necessary requirement that beginRange.location < endRange.location
before continuing the logic.
But please note that -[NSURLSessionDataDelegate URLSession:dataTask:didReceiveData:]
provides no guarantees as to where the NSData
input is being cut: it could be an arbitrary slice of the full response body, and the SDK should probably include some buffering to pick up JSON objects divided in two or more such slices.
Also the previous check for if ([strData containsString:kServerForbiddenStatusCode]) { ... }
is probably not working in all cases when the matched pattern kServerForbiddenStatusCode
of the bytes "code": 403
could be similarly split.
Reproducing the issue
Precise steps to reproduce unknown, as the reproduction of this crash requires a particular kind of response from the Remote Config server and a particular buffering of the response body by NSURLSession
.
Firebase SDK Version
11.4.0
Xcode Version
16.0
Installation Method
Swift Package Manager
Firebase Product(s)
Analytics, Crashlytics, Remote Config
Targeted Platforms
iOS
Relevant Log Output
EXC_BREAKPOINT 0x00000001911cc560
CFString cannot be created from a negative number of bytes
Crashed: com.apple.main-thread
0 CoreFoundation 0x1a4560 __CFStringCreateImmutableFunnel3.cold.1 + 16
1 CoreFoundation 0x7fc4 __CFStringCreateImmutableFunnel3 + 88
2 CoreFoundation 0x4243c -[__NSCFString substringWithRange:] + 160
3 (redacted) 0xd046b4 -[RCNConfigRealtime URLSession:dataTask:didReceiveData:] + 583 (RCNConfigRealtime.m:583)
4 CFNetwork 0xa2c18 CFHostCreateCopy + 2272
5 libdispatch.dylib 0x61c9c _dispatch_call_block_and_release + 24
6 libdispatch.dylib 0x62cc0 _dispatch_client_callout + 16
7 libdispatch.dylib 0x10548 _dispatch_main_queue_drain + 988
8 libdispatch.dylib 0x1015c _dispatch_main_queue_callback_4CF$VARIANT$mp + 36
9 CoreFoundation 0x52ff8 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ + 12
10 CoreFoundation 0x50440 __CFRunLoopRun + 2084
11 CoreFoundation 0x4f7c8 CFRunLoopRunSpecific + 572
12 GraphicsServices 0x1814 GSEventRunModal + 160
13 UIKitCore 0x3d3268 -[UIApplication _run] + 868
14 UIKitCore 0x47d90c UIApplicationMain + 312
15 SwiftUI 0x37d56c OUTLINED_FUNCTION_283 + 352484
16 SwiftUI 0x33652c OUTLINED_FUNCTION_283 + 61604
17 SwiftUI 0x3407e4 OUTLINED_FUNCTION_283 + 103260
18 (redacted) 0x8678 main + 4332357240 (redacted)
19 ??? 0x1b25bb228 (Missing)
If using Swift Package Manager, the project's Package.resolved
Expand Package.resolved
snippet
{
"identity" : "firebase-ios-sdk",
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "8328630971a8fdd8072b36bb22bef732eb15e1f0",
"version" : "11.4.0"
}
}
If using CocoaPods, the project's Podfile.lock
No response