Skip to content
This repository was archived by the owner on Mar 7, 2025. It is now read-only.

Commit 8a3fe29

Browse files
authored
Merge pull request #79 from rollbar/save-json-from-nil
Fix potential nil arguments to JSON serialization
2 parents 9896b5e + 1c824e2 commit 8a3fe29

File tree

3 files changed

+57
-40
lines changed

3 files changed

+57
-40
lines changed

Rollbar/RollbarConfiguration.m

+10-6
Original file line numberDiff line numberDiff line change
@@ -49,17 +49,17 @@ - (id)init {
4949
NSString *cachesDirectory = [paths objectAtIndex:0];
5050
configurationFilePath = [cachesDirectory stringByAppendingPathComponent:CONFIGURATION_FILENAME];
5151
}
52-
52+
5353
if (self = [super init]) {
5454
customData = [NSMutableDictionary dictionaryWithCapacity:10];
5555
self.endpoint = DEFAULT_ENDPOINT;
56-
56+
5757
#ifdef DEBUG
5858
self.environment = @"development";
5959
#else
6060
self.environment = @"unspecified";
6161
#endif
62-
62+
6363
self.crashLevel = @"error";
6464
self.scrubFields = [NSMutableSet new];
6565

@@ -75,17 +75,21 @@ - (id)init {
7575

7676
- (id)initWithLoadedConfiguration {
7777
self = [self init];
78-
78+
7979
NSData *data = [NSData dataWithContentsOfFile:configurationFilePath];
8080
if (data) {
8181
NSDictionary *config = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
82-
82+
83+
if (!config) {
84+
return self;
85+
}
86+
8387
for (NSString *propertyName in config.allKeys) {
8488
id value = [config objectForKey:propertyName];
8589
[self setValue:value forKey:propertyName];
8690
}
8791
}
88-
92+
8993
return self;
9094
}
9195

Rollbar/RollbarNotifier.m

+44-33
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@
3838
@implementation RollbarNotifier
3939

4040
- (id)initWithAccessToken:(NSString*)accessToken configuration:(RollbarConfiguration*)configuration isRoot:(BOOL)isRoot {
41-
41+
4242
if ((self = [super init])) {
4343
[self updateAccessToken:accessToken configuration:configuration isRoot:isRoot];
4444

@@ -47,44 +47,48 @@ - (id)initWithAccessToken:(NSString*)accessToken configuration:(RollbarConfigura
4747
NSString *cachesDirectory = [paths objectAtIndex:0];
4848
queuedItemsFilePath = [cachesDirectory stringByAppendingPathComponent:QUEUED_ITEMS_FILE_NAME];
4949
stateFilePath = [cachesDirectory stringByAppendingPathComponent:STATE_FILE_NAME];
50-
50+
5151
if (![[NSFileManager defaultManager] fileExistsAtPath:queuedItemsFilePath]) {
5252
[[NSFileManager defaultManager] createFileAtPath:queuedItemsFilePath contents:nil attributes:nil];
5353
}
54-
54+
5555
if ([[NSFileManager defaultManager] fileExistsAtPath:stateFilePath]) {
5656
NSData *stateData = [NSData dataWithContentsOfFile:stateFilePath];
57-
NSDictionary *state = [NSJSONSerialization JSONObjectWithData:stateData options:0 error:nil];
58-
59-
queueState = [state mutableCopy];
60-
} else {
57+
if (stateData) {
58+
NSDictionary *state = [NSJSONSerialization JSONObjectWithData:stateData options:0 error:nil];
59+
queueState = [state mutableCopy];
60+
} else {
61+
RollbarLog(@"There was an error restoring saved queue state");
62+
}
63+
}
64+
if (!queueState) {
6165
queueState = [@{@"offset": [NSNumber numberWithUnsignedInt:0],
6266
@"retry_count": [NSNumber numberWithUnsignedInt:0]} mutableCopy];
6367
}
64-
68+
6569
// Deals with sending items that have been queued up
6670
rollbarThread = [[RollbarThread alloc] initWithNotifier:self];
6771
[rollbarThread start];
68-
72+
6973
// Listen for reachability status so that items are only sent when the internet is available
7074
reachability = [RollbarReachability reachabilityForInternetConnection];
71-
75+
7276
isNetworkReachable = [reachability isReachable];
73-
77+
7478
reachability.reachableBlock = ^(RollbarReachability*reach) {
7579
[self captureTelemetryDataForNetwork:true];
7680
isNetworkReachable = YES;
7781
};
78-
82+
7983
reachability.unreachableBlock = ^(RollbarReachability*reach) {
8084
[self captureTelemetryDataForNetwork:false];
8185
isNetworkReachable = NO;
8286
};
83-
87+
8488
[reachability startNotifier];
8589
}
8690
}
87-
91+
8892
return self;
8993
}
9094

@@ -112,71 +116,76 @@ - (void)processSavedItems {
112116
// Don't attempt sending if the network is known to be not reachable
113117
return;
114118
}
115-
119+
116120
__block NSString *lastAccessToken = nil;
117121
NSMutableArray *items = [NSMutableArray array];
118122

119123
NSUInteger startOffset = [queueState[@"offset"] unsignedIntegerValue];
120-
124+
121125
NSFileHandle *fileHandle = [NSFileHandle fileHandleForReadingAtPath:queuedItemsFilePath];
122126
[fileHandle seekToEndOfFile];
123127
__block unsigned long long fileLength = [fileHandle offsetInFile];
124128
[fileHandle closeFile];
125-
129+
126130
if (!fileLength) {
127131
return;
128132
}
129-
133+
130134
// Empty out the queued item file if all items have been processed already
131135
if (startOffset == fileLength) {
132136
[@"" writeToFile:queuedItemsFilePath atomically:YES encoding:NSUTF8StringEncoding error:nil];
133-
137+
134138
queueState[@"offset"] = [NSNumber numberWithUnsignedInteger:0];
135139
queueState[@"retry_count"] = [NSNumber numberWithUnsignedInteger:0];
136140
[self saveQueueState];
137-
141+
138142
return;
139143
}
140-
144+
141145
// Iterate through the items file and send the items in batches.
142146
RollbarFileReader *reader = [[RollbarFileReader alloc] initWithFilePath:queuedItemsFilePath andOffset:startOffset];
143147
[reader enumerateLinesUsingBlock:^(NSString *line, NSUInteger nextOffset, BOOL *stop) {
144-
NSDictionary *payload = [NSJSONSerialization JSONObjectWithData:[line dataUsingEncoding:NSUTF8StringEncoding] options:0 error:nil];
145-
148+
NSData *lineData = [line dataUsingEncoding:NSUTF8StringEncoding];
149+
if (!lineData) {
150+
// All we can do is ignore this line
151+
RollbarLog(@"Error converting file line to NSData");
152+
return;
153+
}
154+
NSDictionary *payload = [NSJSONSerialization JSONObjectWithData:lineData options:0 error:nil];
155+
146156
if (!payload) {
147157
// Ignore this line if it isn't valid json and proceed to the next line
148-
// TODO: report an internal error
158+
RollbarLog(@"Error restoring data from file to JSON");
149159
return;
150160
}
151-
161+
152162
NSString *accessToken = payload[@"access_token"];
153-
163+
154164
// If the max batch size is reached as the file is being processed,
155165
// try sending the current batch before starting a new one
156166
if ([items count] >= MAX_BATCH_SIZE || (lastAccessToken != nil && [accessToken compare:lastAccessToken] != NSOrderedSame)) {
157167
BOOL shouldContinue = [self sendItems:items withAccessToken:lastAccessToken nextOffset:nextOffset];
158-
168+
159169
if (!shouldContinue) {
160170
// Stop processing the file so that the current file offset will be
161171
// retried next time the file is processed
162172
*stop = YES;
163173
return;
164174
}
165-
175+
166176
// The file has had items added since we started iterating through it,
167177
// update the known file length to equal the next offset
168178
if (nextOffset > fileLength) {
169179
fileLength = nextOffset;
170180
}
171-
181+
172182
[items removeAllObjects];
173183
}
174-
175184
[items addObject:payload[@"data"]];
176-
185+
177186
lastAccessToken = accessToken;
178187
}];
179-
188+
180189
// The whole file has been read, send all of the pending items
181190
if ([items count]) {
182191
[self sendItems:items withAccessToken:lastAccessToken nextOffset:(NSUInteger)fileLength];
@@ -482,7 +491,9 @@ - (BOOL)checkPayloadResponse:(NSURLResponse*)response error:(NSError*)error data
482491
return YES;
483492
} else {
484493
RollbarLog(@"There was a problem reporting to Rollbar");
485-
RollbarLog(@"Response: %@", [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]);
494+
if (data) {
495+
RollbarLog(@"Response: %@", [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]);
496+
}
486497
}
487498
}
488499
return NO;

Rollbar/RollbarTelemetry.m

+3-1
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,9 @@ - (void)loadTelemetryData {
208208
NSData *data = [NSData dataWithContentsOfFile:dataFilePath];
209209
if (data) {
210210
NSArray *telemetryDataList = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
211-
dataArray = [telemetryDataList mutableCopy];
211+
if (telemetryDataList) {
212+
dataArray = [telemetryDataList mutableCopy];
213+
}
212214
}
213215
}
214216
}

0 commit comments

Comments
 (0)