Skip to content

Commit 78b9b7f

Browse files
authored
Fixes a bug in custom key and user ID logging (#9289)
1 parent 17e5ae8 commit 78b9b7f

File tree

7 files changed

+85
-14
lines changed

7 files changed

+85
-14
lines changed

Crashlytics/CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
# Unreleased
2+
- [fixed] Fixed an issue where passing nil as a value for a custom key or user ID did not clear the stored value as expected.
3+
14
# v8.9.0
25
- [fixed] Fixed an issue where exceptions with `nil` reasons weren't properly recorded (#8671).
36

Crashlytics/Crashlytics/Components/FIRCLSUserLogging.m

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@
4141
#pragma mark - Prototypes
4242
static void FIRCLSUserLoggingWriteKeysAndValues(NSDictionary *keysAndValues,
4343
FIRCLSUserLoggingKVStorage *storage,
44-
uint32_t *counter);
44+
uint32_t *counter,
45+
BOOL containsNullValue);
4546
static void FIRCLSUserLoggingCheckAndSwapABFiles(FIRCLSUserLoggingABStorage *storage,
4647
const char **activePath,
4748
off_t fileSize);
@@ -75,7 +76,7 @@ void FIRCLSUserLoggingWriteInternalKeyValue(NSString *key, NSString *value) {
7576
NSDictionary *keysAndValues = key ? @{key : value ?: [NSNull null]} : nil;
7677
FIRCLSUserLoggingWriteKeysAndValues(keysAndValues,
7778
&_firclsContext.readonly->logging.internalKVStorage,
78-
&_firclsContext.writable->logging.internalKVCount);
79+
&_firclsContext.writable->logging.internalKVCount, NO);
7980
}
8081

8182
void FIRCLSUserLoggingRecordUserKeyValue(NSString *key, id value) {
@@ -250,6 +251,8 @@ void FIRCLSUserLoggingRecordKeysAndValues(NSDictionary *keysAndValues,
250251
}
251252

252253
NSMutableDictionary *sanitizedKeysAndValues = [keysAndValues mutableCopy];
254+
BOOL containsNullValue = NO;
255+
253256
for (NSString *key in keysAndValues) {
254257
if (!FIRCLSIsValidPointer(key)) {
255258
FIRCLSSDKLogWarn("User provided bad key\n");
@@ -264,23 +267,26 @@ void FIRCLSUserLoggingRecordKeysAndValues(NSDictionary *keysAndValues,
264267
sanitizedKeysAndValues[key] = [NSNull null];
265268
}
266269

267-
if ([value respondsToSelector:@selector(description)]) {
270+
if ([value respondsToSelector:@selector(description)] && ![value isEqual:[NSNull null]]) {
268271
sanitizedKeysAndValues[key] = [value description];
269272
} else {
270273
// passing nil will result in a JSON null being written, which is deserialized as [NSNull
271274
// null], signaling to remove the key during compaction
272275
sanitizedKeysAndValues[key] = [NSNull null];
276+
containsNullValue = YES;
273277
}
274278
}
275279

276280
dispatch_sync(FIRCLSGetLoggingQueue(), ^{
277-
FIRCLSUserLoggingWriteKeysAndValues(sanitizedKeysAndValues, storage, counter);
281+
FIRCLSUserLoggingWriteKeysAndValues(sanitizedKeysAndValues, storage, counter,
282+
containsNullValue);
278283
});
279284
}
280285

281286
static void FIRCLSUserLoggingWriteKeysAndValues(NSDictionary *keysAndValues,
282287
FIRCLSUserLoggingKVStorage *storage,
283-
uint32_t *counter) {
288+
uint32_t *counter,
289+
BOOL containsNullValue) {
284290
FIRCLSFile file;
285291

286292
if (!FIRCLSIsValidPointer(storage) || !FIRCLSIsValidPointer(counter)) {
@@ -297,7 +303,7 @@ static void FIRCLSUserLoggingWriteKeysAndValues(NSDictionary *keysAndValues,
297303
FIRCLSFileClose(&file);
298304

299305
*counter += keysAndValues.count;
300-
if (*counter >= storage->maxIncrementalCount) {
306+
if (*counter >= storage->maxIncrementalCount || containsNullValue) {
301307
dispatch_async(FIRCLSGetLoggingQueue(), ^{
302308
FIRCLSUserLoggingCompactKVEntries(storage);
303309
*counter = 0;

Crashlytics/Crashlytics/FIRCrashlytics.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -294,13 +294,13 @@ - (void)deleteUnsentReports {
294294
}
295295

296296
#pragma mark - API: setUserID
297-
- (void)setUserID:(NSString *)userID {
297+
- (void)setUserID:(nullable NSString *)userID {
298298
FIRCLSUserLoggingRecordInternalKeyValue(FIRCLSUserIdentifierKey, userID);
299299
}
300300

301301
#pragma mark - API: setCustomValue
302302

303-
- (void)setCustomValue:(id)value forKey:(NSString *)key {
303+
- (void)setCustomValue:(nullable id)value forKey:(NSString *)key {
304304
FIRCLSUserLoggingRecordUserKeyValue(key, value);
305305
}
306306

Crashlytics/Crashlytics/FIRCrashlyticsReport.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ - (void)logWithFormat:(NSString *)format arguments:(va_list)args {
167167

168168
#pragma mark - API: setUserID
169169

170-
- (void)setUserID:(NSString *)userID {
170+
- (void)setUserID:(nullable NSString *)userID {
171171
if (![self checkContextForMethod:@"setUserID:"]) {
172172
return;
173173
}
@@ -178,7 +178,7 @@ - (void)setUserID:(NSString *)userID {
178178

179179
#pragma mark - API: setCustomValue
180180

181-
- (void)setCustomValue:(id)value forKey:(NSString *)key {
181+
- (void)setCustomValue:(nullable id)value forKey:(NSString *)key {
182182
if (![self checkContextForMethod:@"setCustomValue:forKey:"]) {
183183
return;
184184
}

Crashlytics/Crashlytics/Public/FirebaseCrashlytics/FIRCrashlytics.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ NS_SWIFT_NAME(Crashlytics)
8282
* @param value The value to be associated with the key
8383
* @param key A unique key
8484
*/
85-
- (void)setCustomValue:(id)value forKey:(NSString *)key;
85+
- (void)setCustomValue:(nullable id)value forKey:(NSString *)key;
8686
8787
/**
8888
* Sets custom keys and values to be associated with subsequent fatal and non-fatal reports.
@@ -104,7 +104,7 @@ NS_SWIFT_NAME(Crashlytics)
104104
* @param userID An arbitrary user identifier string that associates a user to a record in your
105105
* system.
106106
*/
107-
- (void)setUserID:(NSString *)userID;
107+
- (void)setUserID:(nullable NSString *)userID;
108108
109109
/**
110110
* Records a non-fatal event described by an Error object. The events are

Crashlytics/Crashlytics/Public/FirebaseCrashlytics/FIRCrashlyticsReport.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ NS_SWIFT_NAME(CrashlyticsReport)
7979
* @param value The value to be associated with the key
8080
* @param key A unique key
8181
*/
82-
- (void)setCustomValue:(id)value forKey:(NSString *)key;
82+
- (void)setCustomValue:(nullable id)value forKey:(NSString *)key;
8383

8484
/**
8585
* Sets custom keys and values to be associated with subsequent fatal and non-fatal reports.
@@ -101,7 +101,7 @@ NS_SWIFT_NAME(CrashlyticsReport)
101101
* @param userID An arbitrary user identifier string that associates a user to a record in your
102102
* system.
103103
*/
104-
- (void)setUserID:(NSString *)userID;
104+
- (void)setUserID:(nullable NSString *)userID;
105105

106106
@end
107107

Crashlytics/UnitTests/FIRCrashlyticsReportTests.m

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,29 @@ - (void)testSetUserID {
106106
XCTAssertEqualObjects(entries[0][@"kv"][@"value"], FIRCLSFileHexEncodeString("12345-6"), @"");
107107
}
108108

109+
- (void)testClearUserID {
110+
FIRCrashlyticsReport *report = [self createTempCopyOfReportWithName:@"metadata_only_report"];
111+
112+
// Add a user ID
113+
[report setUserID:@"12345-6"];
114+
NSArray *entries = FIRCLSFileReadSections(
115+
[[report.internalReport pathForContentFile:FIRCLSReportInternalIncrementalKVFile]
116+
fileSystemRepresentation],
117+
false, nil);
118+
119+
XCTAssertEqual([entries count], 1, @"");
120+
121+
// Now remove it
122+
[report setUserID:nil];
123+
124+
entries = FIRCLSFileReadSections(
125+
[[report.internalReport pathForContentFile:FIRCLSReportInternalCompactedKVFile]
126+
fileSystemRepresentation],
127+
false, nil);
128+
129+
XCTAssertEqual([entries count], 0, @"");
130+
}
131+
109132
- (void)testCustomKeysNoExisting {
110133
FIRCrashlyticsReport *report = [self createTempCopyOfReportWithName:@"metadata_only_report"];
111134

@@ -168,6 +191,45 @@ - (void)testCustomKeysWithExisting {
168191
XCTAssertEqualObjects(entries[4][@"kv"][@"value"], FIRCLSFileHexEncodeString("10"), @"");
169192
}
170193

194+
- (void)testClearCustomKeys {
195+
FIRCrashlyticsReport *report = [self createTempCopyOfReportWithName:@"metadata_only_report"];
196+
197+
// Add keys
198+
[report setCustomValue:@"hello" forKey:@"mykey"];
199+
[report setCustomValue:@"goodbye" forKey:@"anotherkey"];
200+
201+
[report setCustomKeysAndValues:@{
202+
@"is_test" : @(YES),
203+
@"test_number" : @(10),
204+
}];
205+
206+
NSArray *entries = FIRCLSFileReadSections(
207+
[[report.internalReport pathForContentFile:FIRCLSReportUserIncrementalKVFile]
208+
fileSystemRepresentation],
209+
false, nil);
210+
211+
XCTAssertEqual([entries count], 4, @"");
212+
213+
// Now remove them
214+
[report setCustomValue:nil forKey:@"mykey"];
215+
[report setCustomValue:nil forKey:@"anotherkey"];
216+
entries = FIRCLSFileReadSections(
217+
[[report.internalReport pathForContentFile:FIRCLSReportUserIncrementalKVFile]
218+
fileSystemRepresentation],
219+
false, nil);
220+
[report setCustomKeysAndValues:@{
221+
@"is_test" : [NSNull null],
222+
@"test_number" : [NSNull null],
223+
}];
224+
225+
entries = FIRCLSFileReadSections(
226+
[[report.internalReport pathForContentFile:FIRCLSReportInternalCompactedKVFile]
227+
fileSystemRepresentation],
228+
false, nil);
229+
230+
XCTAssertEqual([entries count], 0, @"");
231+
}
232+
171233
- (void)testCustomKeysLimits {
172234
FIRCrashlyticsReport *report = [self createTempCopyOfReportWithName:@"ios_all_files_crash"];
173235

0 commit comments

Comments
 (0)