Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Removed non-thread safe date formatter #758

Merged
merged 1 commit into from
Jul 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Bugsnag.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -1480,7 +1480,6 @@
008969112486DAD000DC48C2 /* BSG_KSMachApple.h */,
008969122486DAD000DC48C2 /* BSG_KSString.h */,
008969132486DAD000DC48C2 /* BSG_KSMach.c */,
008969142486DAD000DC48C2 /* BSG_RFC3339DateTool.m */,
008969152486DAD000DC48C2 /* BSG_KSLogger.h */,
008969162486DAD000DC48C2 /* BSG_KSBacktrace_Private.h */,
008969172486DAD000DC48C2 /* BSG_KSMach_Arm64.c */,
Expand All @@ -1498,7 +1497,6 @@
008969242486DAD000DC48C2 /* BSG_KSString.c */,
008969252486DAD000DC48C2 /* BSG_KSObjC.c */,
008969262486DAD000DC48C2 /* BSG_KSLogger.m */,
008969272486DAD000DC48C2 /* BSG_RFC3339DateTool.h */,
008969282486DAD000DC48C2 /* BSG_KSMach.h */,
);
path = Tools;
Expand Down Expand Up @@ -1685,6 +1683,8 @@
00AD1CF524869EE500A27979 /* Helpers */ = {
isa = PBXGroup;
children = (
008969272486DAD000DC48C2 /* BSG_RFC3339DateTool.h */,
008969142486DAD000DC48C2 /* BSG_RFC3339DateTool.m */,
008968112486DA5600DC48C2 /* BSGSerialization.h */,
008968162486DA5600DC48C2 /* BSGSerialization.m */,
008968102486DA5600DC48C2 /* BugsnagCollections.h */,
Expand Down
7 changes: 2 additions & 5 deletions Bugsnag/BSGOutOfMemoryWatchdog.m
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#import "BugsnagSessionTracker.h"
#import "Private.h"
#import "BugsnagErrorTypes.h"
#import "BSG_RFC3339DateTool.h"

@interface BSGOutOfMemoryWatchdog ()
@property(nonatomic, getter=isWatching) BOOL watching;
Expand All @@ -26,10 +27,6 @@ @interface BSGOutOfMemoryWatchdog ()
@property(nonatomic) NSString *codeBundleId;
@end

@interface Bugsnag ()
+ (NSDateFormatter *_Nonnull)payloadDateFormatter;
@end

@implementation BSGOutOfMemoryWatchdog

- (instancetype)init {
Expand Down Expand Up @@ -152,7 +149,7 @@ - (void)handleTransitionToBackground:(NSNotification *)note {
}

- (void)handleLowMemoryChange:(NSNotification *)note {
self.cachedFileInfo[@"device"][@"lowMemory"] = [[Bugsnag payloadDateFormatter]
self.cachedFileInfo[@"device"][@"lowMemory"] = [BSG_RFC3339DateTool
stringFromDate:[NSDate date]];
[self writeSentinelFile];
}
Expand Down
11 changes: 0 additions & 11 deletions Bugsnag/Bugsnag.m
Original file line number Diff line number Diff line change
Expand Up @@ -210,17 +210,6 @@ + (BOOL)resumeSession {
}
}

+ (NSDateFormatter *)payloadDateFormatter {
static NSDateFormatter *formatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
formatter = [NSDateFormatter new];
formatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZ";
formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
});
return formatter;
}

+ (void)addRuntimeVersionInfo:(NSString *)info
withKey:(NSString *)key {
if ([self bugsnagStarted]) {
Expand Down
6 changes: 1 addition & 5 deletions Bugsnag/Client/BugsnagClient.m
Original file line number Diff line number Diff line change
Expand Up @@ -353,10 +353,6 @@ @interface BugsnagUser ()
- (instancetype)initWithDictionary:(NSDictionary *)dict;
@end

@interface Bugsnag ()
+ (NSDateFormatter *_Nonnull)payloadDateFormatter;
@end

@interface BugsnagBreadcrumbs ()
@property(nonatomic, readwrite, strong) NSMutableArray *breadcrumbs;
@end
Expand Down Expand Up @@ -1177,7 +1173,7 @@ - (void)orientationChanged:(NSNotification *)notification {
}

- (void)lowMemoryWarning:(NSNotification *)notif {
[self.state addMetadata:[[Bugsnag payloadDateFormatter] stringFromDate:[NSDate date]]
[self.state addMetadata:[BSG_RFC3339DateTool stringFromDate:[NSDate date]]
withKey:BSEventLowMemoryWarning
toSection:BSGKeyDeviceState];

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,23 +24,49 @@

#import "BSG_RFC3339DateTool.h"

@interface BSG_RFC3339DateTool ()
+ (NSDateFormatter *)iosFormatterInstance;
@end

@implementation BSG_RFC3339DateTool

static NSString *const kDateFormatterKey = @"RfcDateFormatter";
static NSString *const kRfcDateFormatterKey = @"RfcDateFormatter";
static NSString *const kIsoDateFormatterKey = @"IsoDateFormatter";

+ (NSDateFormatter *)sharedInstance {
NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
NSDateFormatter *formatter = threadDict[kDateFormatterKey];

NSDateFormatter *formatter = threadDict[kRfcDateFormatterKey];
if (formatter == nil) {
formatter = [NSDateFormatter new];
NSLocale *locale =
[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
[formatter setLocale:locale];
[formatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
threadDict[kDateFormatterKey] = formatter;
threadDict[kRfcDateFormatterKey] = formatter;
}

formatter = threadDict[kRfcDateFormatterKey];
return formatter;
}

/**
Used internally to convert any dates with timezones (from older notifier versions) to Zulu time
*/
+ (NSDateFormatter *)iosFormatterInstance {
NSMutableDictionary *threadDict = [[NSThread currentThread] threadDictionary];
NSDateFormatter *formatter = threadDict[kIsoDateFormatterKey];
if (formatter == nil) {
formatter = [NSDateFormatter new];
NSLocale *locale =
[[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"];
[formatter setLocale:locale];
[formatter setDateFormat:@"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZ"];
[formatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
threadDict[kIsoDateFormatterKey] = formatter;
}

formatter = threadDict[kIsoDateFormatterKey];
return formatter;
}

Expand All @@ -55,7 +81,11 @@ + (NSDate *)dateFromString:(NSString *)string {
if (![string isKindOfClass:[NSString class]]) {
return nil;
}
return [[self sharedInstance] dateFromString:string];
NSDate *date = [[self sharedInstance] dateFromString:string];
if (!date) {
date = [[self iosFormatterInstance] dateFromString:string];
}
return date;
}

+ (NSString *)stringFromUNIXTimestamp:(unsigned long long)timestamp {
Expand Down
11 changes: 4 additions & 7 deletions Bugsnag/Payload/BugsnagBreadcrumb.m
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
//
#import "BSG_RFC3339DateTool.h"

#import "BugsnagBreadcrumb.h"
#import "BugsnagBreadcrumbs.h"
#import "Bugsnag.h"
Expand Down Expand Up @@ -72,10 +74,6 @@ BSGBreadcrumbType BSGBreadcrumbTypeFromString(NSString *value) {
}
}

@interface Bugsnag ()
+ (NSDateFormatter *_Nonnull)payloadDateFormatter;
@end

@implementation BugsnagBreadcrumb

- (instancetype)init {
Expand All @@ -93,8 +91,7 @@ - (BOOL)isValid {

- (NSDictionary *)objectValue {
@synchronized (self) {
NSString *timestamp =
[[Bugsnag payloadDateFormatter] stringFromDate:_timestamp];
NSString *timestamp = [BSG_RFC3339DateTool stringFromDate:_timestamp];
if (timestamp && _message.length > 0) {
NSMutableDictionary *metadata = [NSMutableDictionary new];
for (NSString *key in _metadata) {
Expand Down Expand Up @@ -212,7 +209,7 @@ + (instancetype)breadcrumbFromDict:(NSDictionary *)dict {
return [self breadcrumbWithBlock:^(BugsnagBreadcrumb *crumb) {
crumb.message = dict[BSGKeyMessage] ?: dict[BSGKeyName];
crumb.metadata = dict[BSGKeyMetadata] ?: dict[@"metadata"];
crumb.timestamp = [[Bugsnag payloadDateFormatter] dateFromString:dict[BSGKeyTimestamp]];
crumb.timestamp = [BSG_RFC3339DateTool dateFromString:dict[BSGKeyTimestamp]];
crumb.type = BSGBreadcrumbTypeFromString(dict[BSGKeyType]);
}];
}
Expand Down
22 changes: 4 additions & 18 deletions Bugsnag/Payload/BugsnagDeviceWithState.m
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//

#import "BugsnagPlatformConditional.h"
#import "BSG_RFC3339DateTool.h"

#import "BugsnagDeviceWithState.h"
#import "BugsnagCollections.h"
Expand Down Expand Up @@ -53,30 +54,15 @@
return freeBytes;
}

@interface Bugsnag ()
+ (NSDateFormatter *)payloadDateFormatter;
@end

@interface BugsnagDevice ()
+ (void)populateFields:(BugsnagDevice *)device
dictionary:(NSDictionary *)event;

- (NSDictionary *)toDictionary;
@end

@interface BugsnagDeviceWithState ()
@property (nonatomic, readonly) NSDateFormatter *formatter;
@end

@implementation BugsnagDeviceWithState

- (instancetype)init {
if (self = [super init]) {
_formatter = [Bugsnag payloadDateFormatter];
}
return self;
}

+ (BugsnagDeviceWithState *) deviceFromJson:(NSDictionary *)json {
BugsnagDeviceWithState *device = [BugsnagDeviceWithState new];
device.id = json[@"id"];
Expand All @@ -99,7 +85,7 @@ + (BugsnagDeviceWithState *) deviceFromJson:(NSDictionary *)json {

id time = json[@"time"];
if (time && [time isKindOfClass:[NSString class]]) {
device.time = [device.formatter dateFromString:time];
device.time = [BSG_RFC3339DateTool dateFromString:time];
}
return device;
}
Expand All @@ -125,7 +111,7 @@ + (BugsnagDeviceWithState *)deviceWithDictionary:(NSDictionary *)event {
NSString *val = [event valueForKeyPath:@"report.timestamp"];

if (val != nil) {
device.time = [device.formatter dateFromString:val];
device.time = [BSG_RFC3339DateTool dateFromString:val];
}
return device;
}
Expand All @@ -138,7 +124,7 @@ - (NSDictionary *)toDictionary {
BSGDictInsertIfNotNil(dict, self.orientation, @"orientation");

if (self.time != nil) {
BSGDictInsertIfNotNil(dict, [self.formatter stringFromDate:self.time], @"time");
BSGDictInsertIfNotNil(dict, [BSG_RFC3339DateTool stringFromDate:self.time], @"time");
}
return dict;
}
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ Changelog
* Synchronize access to sessions being delivered in de-duplication code
[#756](https://github.com/bugsnag/bugsnag-cocoa/pull/756)

* Removed non-thread safe date formatter
[#758](https://github.com/bugsnag/bugsnag-cocoa/pull/758)

## 6.1.1 (2020-07-16)

### Bug fixes
Expand Down
1 change: 0 additions & 1 deletion Tests/BugsnagClientMirrorTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@ - (void)setUp {
self.clientWhitelist = [NSSet setWithArray:@[
@"startWithApiKey: @24@0:8@16",
@"startWithConfiguration: @24@0:8@16",
@"payloadDateFormatter @16@0:8",
@"updateCodeBundleId: v24@0:8@16",
@"instance @16@0:8",
@"client @16@0:8",
Expand Down
2 changes: 1 addition & 1 deletion Tests/BugsnagErrorReportSinkTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ - (void)testEventDevice {
XCTAssertEqualObjects(device[@"jailbroken"], @YES);
XCTAssertEqualObjects(device[@"freeMemory"], @742920192);
XCTAssertEqualObjects(device[@"orientation"], @"unknown");
XCTAssertEqualObjects(device[@"time"], @"2014-12-02T01:56:13+0000");
XCTAssertEqualObjects(device[@"time"], @"2014-12-02T01:56:13Z");
}

- (void)testEventApp {
Expand Down
22 changes: 15 additions & 7 deletions Tests/BugsnagEventPersistLoadTest.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@
#import "BugsnagHandledState.h"
#import "Bugsnag.h"

@interface Bugsnag ()
+ (NSDateFormatter *)payloadDateFormatter;
@end
#import "BugsnagError.h"
#import "BugsnagStackframe.h"
#import "BugsnagThread.h"
Expand Down Expand Up @@ -170,14 +167,18 @@ - (void)testDeviceFieldsOverride {
}
}
}];

NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZ";
formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];

BugsnagDeviceWithState *device = event.device;
XCTAssertEqualObjects(@920234094, device.freeDisk);
XCTAssertEqualObjects(@5092340923, device.freeMemory);
XCTAssertEqualObjects(@92092340923, device.totalMemory);
XCTAssertEqualObjects(@"landscape", device.orientation);
XCTAssertFalse(device.jailbroken);
NSString *date = [device.formatter stringFromDate:device.time];
NSString *date = [formatter stringFromDate:device.time];
XCTAssertEqualObjects(@"2020-05-11T15:36:09+0000", date);

XCTAssertEqualObjects(@"f0a9b99", device.id);
Expand Down Expand Up @@ -264,7 +265,11 @@ - (void)testBreadcrumbsOverride {
XCTAssertEqual(1, [event.breadcrumbs count]);
XCTAssertEqual(BSGBreadcrumbTypeManual, breadcrumb.type);
XCTAssertEqualObjects(@"installed NDK", breadcrumb.message);
NSDate *date = [[Bugsnag payloadDateFormatter] dateFromString:@"2020-02-14T16:12:23+001"];

NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZ";
formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSDate *date = [formatter dateFromString:@"2020-02-14T16:12:23+001"];
XCTAssertEqualObjects(date, breadcrumb.timestamp);
XCTAssertEqualObjects(@{
@"custom": @{
Expand Down Expand Up @@ -348,8 +353,11 @@ - (void)testSessionOverride {
}
}
}];

NSDate *date = [[Bugsnag payloadDateFormatter] dateFromString:@"2020-05-18T13:13:24Z"];

NSDateFormatter *formatter = [NSDateFormatter new];
formatter.dateFormat = @"yyyy'-'MM'-'dd'T'HH':'mm':'ssZZZ";
formatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSDate *date = [formatter dateFromString:@"2020-05-18T13:13:24Z"];
XCTAssertEqualObjects(date, event.session.startedAt);
XCTAssertEqualObjects(@"123", event.session.id);
XCTAssertEqual(1, event.session.unhandledCount);
Expand Down
19 changes: 19 additions & 0 deletions Tests/KSCrash/RFC3339DateTool_Tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,25 @@ - (void) testDateFromString
XCTAssertEqualObjects(actual, expected, @"");
}

- (void) testDateFromStringWithTimezone
{
NSDate* expected = [self gmtDateWithYear:2000 month:1 day:2 hour:3 minute:4 second:5];
NSDate* actual = [BSG_RFC3339DateTool dateFromString:@"2000-01-02T03:04:05+0000"];

XCTAssertEqualObjects(actual, expected, @"");
}

- (void) testDateFromStringWithTimezonePlus2
{
NSDate* expected = [self gmtDateWithYear:2000 month:1 day:2 hour:1 minute:4 second:5];
NSDate* actual = [BSG_RFC3339DateTool dateFromString:@"2000-01-02T03:04:05+0200"];

XCTAssertEqualObjects(actual, expected, @"");

// Convert back again to verify overall effect
XCTAssertEqualObjects([BSG_RFC3339DateTool stringFromDate:actual], @"2000-01-02T01:04:05Z");
}

- (void) testStringFromUnixTimestamp
{
NSDate* date = [self gmtDateWithYear:2000 month:1 day:2 hour:3 minute:4 second:5];
Expand Down
4 changes: 2 additions & 2 deletions Tests/report.json
Original file line number Diff line number Diff line change
Expand Up @@ -2103,8 +2103,8 @@
"depth": 4,
"severity": "warning",
"breadcrumbs": [
{"message": "App launched", "timestamp": "2020-02-14T16:12:22+0000", "type": "manual", "metaData":{}},
{"message": "Tapped button", "timestamp": "2020-02-14T16:12:24+0000", "type": "manual", "metaData":{}}
{"message": "App launched", "timestamp": "2020-02-14T16:12:22Z", "type": "manual", "metaData":{}},
{"message": "Tapped button", "timestamp": "2020-02-14T16:12:24Z", "type": "manual", "metaData":{}}
]
}
}
Expand Down