From 0071d351168c8edc0f1640b2b804c3328a8f7fc6 Mon Sep 17 00:00:00 2001 From: Nick Dowell Date: Wed, 6 Jan 2021 14:57:46 +0000 Subject: [PATCH 1/3] deps(react-native): Bump bugsnag-cocoa to v6.5.0 --- .../react-native/ios/.bugsnag-cocoa-version | 2 +- .../vendor/bugsnag-cocoa/Bugsnag.podspec.json | 4 +- .../Bugsnag.xcodeproj/project.pbxproj | 84 ++-- .../Breadcrumbs/BSGNotificationBreadcrumbs.h | 57 +++ .../Breadcrumbs/BSGNotificationBreadcrumbs.m | 303 +++++++++++++ .../Bugsnag/BugsnagCrashSentry.h | 3 + .../Bugsnag/BugsnagCrashSentry.m | 9 +- .../Bugsnag/BugsnagErrorReportSink+Private.h | 2 + .../Bugsnag/BugsnagErrorReportSink.h | 18 +- .../Bugsnag/BugsnagErrorReportSink.m | 51 ++- .../Bugsnag/BugsnagSessionTracker.m | 20 +- .../Bugsnag/Client/BugsnagClient.m | 407 ++---------------- .../Configuration/BSGConfigurationBuilder.m | 23 +- .../BugsnagConfiguration+Private.h | 11 +- .../Configuration/BugsnagConfiguration.m | 208 ++++----- .../Delivery/BugsnagErrorReportApiClient.m | 5 +- .../BugsnagSessionTrackingApiClient.h | 5 +- .../BugsnagSessionTrackingApiClient.m | 15 +- .../Bugsnag/Helpers/BSGCachesDirectory.m | 9 +- .../Bugsnag/Helpers/BugsnagKeys.h | 4 +- .../Bugsnag/Helpers/BugsnagKeys.m | 4 +- .../Bugsnag/Helpers/BugsnagLogger.h | 17 +- .../Source/KSCrash/Recording/BSG_KSCrash.m | 2 +- .../KSCrash/Recording/BSG_KSCrashReport.c | 25 ++ .../Recording/BSG_KSCrashReportFields.h | 1 + .../KSCrash/Recording/Tools/BSG_KSLogger.h | 18 + .../Recording/Tools/BSG_KSMachHeaders.c | 340 +++++++++++++++ .../Recording/Tools/BSG_KSMachHeaders.h | 7 + .../Bugsnag/Payload/BugsnagError+Private.h | 3 + .../Bugsnag/Payload/BugsnagError.m | 46 +- .../Bugsnag/Payload/BugsnagEvent+Private.h | 2 +- .../Bugsnag/Payload/BugsnagEvent.m | 24 +- .../Bugsnag/Payload/BugsnagNotifier.m | 2 +- .../Payload/BugsnagSessionTrackingPayload.h | 4 +- .../Payload/BugsnagSessionTrackingPayload.m | 5 +- .../Bugsnag/Payload/BugsnagThread+Private.h | 2 + .../Bugsnag/Payload/BugsnagThread.m | 15 +- .../Bugsnag/Storage/BugsnagFileStore.m | 27 +- .../Bugsnag/Storage/BugsnagSessionFileStore.h | 3 +- .../Bugsnag/Storage/BugsnagSessionFileStore.m | 26 +- .../include/Bugsnag/BugsnagConfiguration.h | 30 ++ .../Bugsnag/include/Bugsnag/BugsnagEvent.h | 2 +- .../ios/vendor/bugsnag-cocoa/CHANGELOG.md | 21 + .../vendor/bugsnag-cocoa/Framework/Info.plist | 2 +- .../ios/vendor/bugsnag-cocoa/VERSION | 2 +- 45 files changed, 1202 insertions(+), 668 deletions(-) create mode 100644 packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Breadcrumbs/BSGNotificationBreadcrumbs.h create mode 100644 packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Breadcrumbs/BSGNotificationBreadcrumbs.m create mode 100644 packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachHeaders.c diff --git a/packages/react-native/ios/.bugsnag-cocoa-version b/packages/react-native/ios/.bugsnag-cocoa-version index 5575cd6071..ebdb49639a 100644 --- a/packages/react-native/ios/.bugsnag-cocoa-version +++ b/packages/react-native/ios/.bugsnag-cocoa-version @@ -1 +1 @@ -59881aff8a17e68b6027aac3f3ac0aa05d266cdc +75ea085426f483b2fd46dbcae9a3a5d2a3f5496c diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag.podspec.json b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag.podspec.json index 5de71ad21b..fdb946e55e 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag.podspec.json +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag.podspec.json @@ -1,6 +1,6 @@ { "name": "Bugsnag", - "version": "6.4.1", + "version": "6.5.0", "summary": "The Bugsnag crash reporting framework for Apple platforms.", "homepage": "https://bugsnag.com", "license": "MIT", @@ -9,7 +9,7 @@ }, "source": { "git": "https://github.com/bugsnag/bugsnag-cocoa.git", - "tag": "v6.4.1" + "tag": "v6.5.0" }, "frameworks": [ "Foundation", diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag.xcodeproj/project.pbxproj b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag.xcodeproj/project.pbxproj index 3ba9fe84b1..356219d2aa 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag.xcodeproj/project.pbxproj +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag.xcodeproj/project.pbxproj @@ -34,9 +34,6 @@ 008966F42486D43700DC48C2 /* BugsnagThreadTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A72486D43400DC48C2 /* BugsnagThreadTest.m */; }; 008966F52486D43700DC48C2 /* BugsnagThreadTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A72486D43400DC48C2 /* BugsnagThreadTest.m */; }; 008966F62486D43700DC48C2 /* BugsnagThreadTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A72486D43400DC48C2 /* BugsnagThreadTest.m */; }; - 008966F72486D43700DC48C2 /* RegisterErrorDataTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A92486D43400DC48C2 /* RegisterErrorDataTest.m */; }; - 008966F82486D43700DC48C2 /* RegisterErrorDataTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A92486D43400DC48C2 /* RegisterErrorDataTest.m */; }; - 008966F92486D43700DC48C2 /* RegisterErrorDataTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966A92486D43400DC48C2 /* RegisterErrorDataTest.m */; }; 008966FD2486D43700DC48C2 /* BugsnagOnBreadcrumbTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966AB2486D43500DC48C2 /* BugsnagOnBreadcrumbTest.m */; }; 008966FE2486D43700DC48C2 /* BugsnagOnBreadcrumbTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966AB2486D43500DC48C2 /* BugsnagOnBreadcrumbTest.m */; }; 008966FF2486D43700DC48C2 /* BugsnagOnBreadcrumbTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 008966AB2486D43500DC48C2 /* BugsnagOnBreadcrumbTest.m */; }; @@ -423,9 +420,9 @@ 008969812486DAD100DC48C2 /* BSG_KSObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0089690F2486DAD000DC48C2 /* BSG_KSObjC.h */; }; 008969822486DAD100DC48C2 /* BSG_KSObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0089690F2486DAD000DC48C2 /* BSG_KSObjC.h */; }; 008969832486DAD100DC48C2 /* BSG_KSObjC.h in Headers */ = {isa = PBXBuildFile; fileRef = 0089690F2486DAD000DC48C2 /* BSG_KSObjC.h */; }; - 008969842486DAD100DC48C2 /* BSG_KSMachHeaders.m in Sources */ = {isa = PBXBuildFile; fileRef = 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.m */; }; - 008969852486DAD100DC48C2 /* BSG_KSMachHeaders.m in Sources */ = {isa = PBXBuildFile; fileRef = 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.m */; }; - 008969862486DAD100DC48C2 /* BSG_KSMachHeaders.m in Sources */ = {isa = PBXBuildFile; fileRef = 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.m */; }; + 008969842486DAD100DC48C2 /* BSG_KSMachHeaders.c in Sources */ = {isa = PBXBuildFile; fileRef = 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.c */; }; + 008969852486DAD100DC48C2 /* BSG_KSMachHeaders.c in Sources */ = {isa = PBXBuildFile; fileRef = 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.c */; }; + 008969862486DAD100DC48C2 /* BSG_KSMachHeaders.c in Sources */ = {isa = PBXBuildFile; fileRef = 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.c */; }; 008969872486DAD100DC48C2 /* BSG_KSMachApple.h in Headers */ = {isa = PBXBuildFile; fileRef = 008969112486DAD000DC48C2 /* BSG_KSMachApple.h */; }; 008969882486DAD100DC48C2 /* BSG_KSMachApple.h in Headers */ = {isa = PBXBuildFile; fileRef = 008969112486DAD000DC48C2 /* BSG_KSMachApple.h */; }; 008969892486DAD100DC48C2 /* BSG_KSMachApple.h in Headers */ = {isa = PBXBuildFile; fileRef = 008969112486DAD000DC48C2 /* BSG_KSMachApple.h */; }; @@ -609,13 +606,6 @@ 00AD1C7C24869B0E00A27979 /* Bugsnag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00AD1C7224869B0E00A27979 /* Bugsnag.framework */; }; 00AD1CB624869C1200A27979 /* Bugsnag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00AD1CAD24869C1200A27979 /* Bugsnag.framework */; }; 00AD1CD224869C2400A27979 /* Bugsnag.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00AD1CC924869C2400A27979 /* Bugsnag.framework */; }; - 00AD1F022486A17900A27979 /* RegisterErrorData.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1EF42486A17600A27979 /* RegisterErrorData.h */; }; - 00AD1F032486A17900A27979 /* RegisterErrorData.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1EF42486A17600A27979 /* RegisterErrorData.h */; }; - 00AD1F042486A17900A27979 /* RegisterErrorData.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1EF42486A17600A27979 /* RegisterErrorData.h */; }; - 00AD1F052486A17900A27979 /* RegisterErrorData.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EF52486A17600A27979 /* RegisterErrorData.m */; }; - 00AD1F062486A17900A27979 /* RegisterErrorData.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EF52486A17600A27979 /* RegisterErrorData.m */; }; - 00AD1F072486A17900A27979 /* RegisterErrorData.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EF52486A17600A27979 /* RegisterErrorData.m */; }; - 00AD1F082486A17900A27979 /* RegisterErrorData.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EF52486A17600A27979 /* RegisterErrorData.m */; }; 00AD1F102486A17900A27979 /* BugsnagSessionTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1EF82486A17700A27979 /* BugsnagSessionTracker.h */; }; 00AD1F112486A17900A27979 /* BugsnagSessionTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1EF82486A17700A27979 /* BugsnagSessionTracker.h */; }; 00AD1F122486A17900A27979 /* BugsnagSessionTracker.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1EF82486A17700A27979 /* BugsnagSessionTracker.h */; }; @@ -646,6 +636,19 @@ 0126DF1D257A92860031A70C /* BugsnagSession+Private.h in Headers */ = {isa = PBXBuildFile; fileRef = 0126DF1A257A92860031A70C /* BugsnagSession+Private.h */; }; 0140D29A25767C9A00FD0306 /* BugsnagApiClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9103632502320A00E9D1E2 /* BugsnagApiClientTest.m */; }; 01447605256684500018AB94 /* BugsnagApiClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9103632502320A00E9D1E2 /* BugsnagApiClientTest.m */; }; + 016875C6258D003200DFFF69 /* NSUserDefaultsStub.m in Sources */ = {isa = PBXBuildFile; fileRef = 016875C5258D003200DFFF69 /* NSUserDefaultsStub.m */; }; + 016875C7258D003200DFFF69 /* NSUserDefaultsStub.m in Sources */ = {isa = PBXBuildFile; fileRef = 016875C5258D003200DFFF69 /* NSUserDefaultsStub.m */; }; + 016875C8258D003200DFFF69 /* NSUserDefaultsStub.m in Sources */ = {isa = PBXBuildFile; fileRef = 016875C5258D003200DFFF69 /* NSUserDefaultsStub.m */; }; + 01468F5225876DC1002B0519 /* BSGNotificationBreadcrumbs.h in Headers */ = {isa = PBXBuildFile; fileRef = 01468F5025876DC1002B0519 /* BSGNotificationBreadcrumbs.h */; }; + 01468F5325876DC1002B0519 /* BSGNotificationBreadcrumbs.h in Headers */ = {isa = PBXBuildFile; fileRef = 01468F5025876DC1002B0519 /* BSGNotificationBreadcrumbs.h */; }; + 01468F5425876DC1002B0519 /* BSGNotificationBreadcrumbs.h in Headers */ = {isa = PBXBuildFile; fileRef = 01468F5025876DC1002B0519 /* BSGNotificationBreadcrumbs.h */; }; + 01468F5525876DC1002B0519 /* BSGNotificationBreadcrumbs.m in Sources */ = {isa = PBXBuildFile; fileRef = 01468F5125876DC1002B0519 /* BSGNotificationBreadcrumbs.m */; }; + 01468F5625876DC1002B0519 /* BSGNotificationBreadcrumbs.m in Sources */ = {isa = PBXBuildFile; fileRef = 01468F5125876DC1002B0519 /* BSGNotificationBreadcrumbs.m */; }; + 01468F5725876DC1002B0519 /* BSGNotificationBreadcrumbs.m in Sources */ = {isa = PBXBuildFile; fileRef = 01468F5125876DC1002B0519 /* BSGNotificationBreadcrumbs.m */; }; + 01468F5825876DC1002B0519 /* BSGNotificationBreadcrumbs.m in Sources */ = {isa = PBXBuildFile; fileRef = 01468F5125876DC1002B0519 /* BSGNotificationBreadcrumbs.m */; }; + 0163BF5925823D8D008DC28B /* NotificationBreadcrumbTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0163BF5825823D8D008DC28B /* NotificationBreadcrumbTests.m */; }; + 0163BF5A25823D8D008DC28B /* NotificationBreadcrumbTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0163BF5825823D8D008DC28B /* NotificationBreadcrumbTests.m */; }; + 0163BF5B25823D8D008DC28B /* NotificationBreadcrumbTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 0163BF5825823D8D008DC28B /* NotificationBreadcrumbTests.m */; }; 0187D464255BD7B800C503D9 /* BugsnagApiClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CB9103632502320A00E9D1E2 /* BugsnagApiClientTest.m */; }; 01B14C56251CE55F00118748 /* report-react-native-promise-rejection.json in Resources */ = {isa = PBXBuildFile; fileRef = 01B14C55251CE55F00118748 /* report-react-native-promise-rejection.json */; }; 01B14C57251CE55F00118748 /* report-react-native-promise-rejection.json in Resources */ = {isa = PBXBuildFile; fileRef = 01B14C55251CE55F00118748 /* report-react-native-promise-rejection.json */; }; @@ -794,7 +797,7 @@ E701FAB12490EFE8008D842F /* ConfigurationApiValidationTest.m in Sources */ = {isa = PBXBuildFile; fileRef = E701FAAE2490EFE8008D842F /* ConfigurationApiValidationTest.m */; }; E74628FC248907C100F92D67 /* BSG_KSCrashDoctor.m in Sources */ = {isa = PBXBuildFile; fileRef = 008969002486DAD000DC48C2 /* BSG_KSCrashDoctor.m */; }; E74628FD248907C100F92D67 /* BSG_KSJSONCodecObjC.m in Sources */ = {isa = PBXBuildFile; fileRef = 008969082486DAD000DC48C2 /* BSG_KSJSONCodecObjC.m */; }; - E74628FF248907C100F92D67 /* BSG_KSMachHeaders.m in Sources */ = {isa = PBXBuildFile; fileRef = 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.m */; }; + E74628FF248907C100F92D67 /* BSG_KSMachHeaders.c in Sources */ = {isa = PBXBuildFile; fileRef = 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.c */; }; E7462900248907C100F92D67 /* NSError+BSG_SimpleConstructor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0089691E2486DAD000DC48C2 /* NSError+BSG_SimpleConstructor.m */; }; E7462901248907C100F92D67 /* BSG_KSLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 008969262486DAD000DC48C2 /* BSG_KSLogger.m */; }; E7462902248907C100F92D67 /* BSG_KSCrashState.m in Sources */ = {isa = PBXBuildFile; fileRef = 008969292486DAD000DC48C2 /* BSG_KSCrashState.m */; }; @@ -901,7 +904,6 @@ E746299524890D3200F92D67 /* BugsnagCrashSentry.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00AD1F002486A17900A27979 /* BugsnagCrashSentry.h */; }; E746299624890D3200F92D67 /* BugsnagSessionTracker.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00AD1EF82486A17700A27979 /* BugsnagSessionTracker.h */; }; E746299724890D3200F92D67 /* BugsnagErrorReportSink.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00AD1EFD2486A17800A27979 /* BugsnagErrorReportSink.h */; }; - E746299824890D3200F92D67 /* RegisterErrorData.h in CopyFiles */ = {isa = PBXBuildFile; fileRef = 00AD1EF42486A17600A27979 /* RegisterErrorData.h */; }; E75A5CDB248A5D97005D2C74 /* BugsnagErrorReportSink.h in Headers */ = {isa = PBXBuildFile; fileRef = 00AD1EFD2486A17800A27979 /* BugsnagErrorReportSink.h */; }; E75A5CDC248A5DA2005D2C74 /* BugsnagErrorReportSink.m in Sources */ = {isa = PBXBuildFile; fileRef = 00AD1EF92486A17700A27979 /* BugsnagErrorReportSink.m */; }; /* End PBXBuildFile section */ @@ -1020,7 +1022,6 @@ E746299524890D3200F92D67 /* BugsnagCrashSentry.h in CopyFiles */, E746299624890D3200F92D67 /* BugsnagSessionTracker.h in CopyFiles */, E746299724890D3200F92D67 /* BugsnagErrorReportSink.h in CopyFiles */, - E746299824890D3200F92D67 /* RegisterErrorData.h in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1034,7 +1035,6 @@ 008966A62486D43400DC48C2 /* BugsnagMetadataRedactionTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagMetadataRedactionTest.m; sourceTree = ""; }; 008966A72486D43400DC48C2 /* BugsnagThreadTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagThreadTest.m; sourceTree = ""; }; 008966A82486D43400DC48C2 /* BugsnagTestConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugsnagTestConstants.h; sourceTree = ""; }; - 008966A92486D43400DC48C2 /* RegisterErrorDataTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegisterErrorDataTest.m; sourceTree = ""; }; 008966AB2486D43500DC48C2 /* BugsnagOnBreadcrumbTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagOnBreadcrumbTest.m; sourceTree = ""; }; 008966AC2486D43500DC48C2 /* BugsnagEventPersistLoadTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagEventPersistLoadTest.m; sourceTree = ""; }; 008966AD2486D43500DC48C2 /* BugsnagThreadSerializationTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagThreadSerializationTest.m; sourceTree = ""; }; @@ -1162,7 +1162,7 @@ 0089690C2486DAD000DC48C2 /* NSError+BSG_SimpleConstructor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSError+BSG_SimpleConstructor.h"; sourceTree = ""; }; 0089690E2486DAD000DC48C2 /* BSG_KSArchSpecific.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_KSArchSpecific.h; sourceTree = ""; }; 0089690F2486DAD000DC48C2 /* BSG_KSObjC.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_KSObjC.h; sourceTree = ""; }; - 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSG_KSMachHeaders.m; sourceTree = ""; }; + 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = BSG_KSMachHeaders.c; sourceTree = ""; }; 008969112486DAD000DC48C2 /* BSG_KSMachApple.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_KSMachApple.h; sourceTree = ""; }; 008969122486DAD000DC48C2 /* BSG_KSString.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSG_KSString.h; sourceTree = ""; }; 008969132486DAD000DC48C2 /* BSG_KSMach.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = BSG_KSMach.c; sourceTree = ""; }; @@ -1232,8 +1232,6 @@ 00AD1CC924869C2400A27979 /* Bugsnag.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Bugsnag.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 00AD1CD124869C2400A27979 /* Bugsnag-tvOSTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Bugsnag-tvOSTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; }; 00AD1CE424869C6C00A27979 /* libBugsnagStatic.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libBugsnagStatic.a; sourceTree = BUILT_PRODUCTS_DIR; }; - 00AD1EF42486A17600A27979 /* RegisterErrorData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RegisterErrorData.h; sourceTree = ""; }; - 00AD1EF52486A17600A27979 /* RegisterErrorData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RegisterErrorData.m; sourceTree = ""; }; 00AD1EF82486A17700A27979 /* BugsnagSessionTracker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugsnagSessionTracker.h; sourceTree = ""; }; 00AD1EF92486A17700A27979 /* BugsnagErrorReportSink.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BugsnagErrorReportSink.m; sourceTree = ""; }; 00AD1EFD2486A17800A27979 /* BugsnagErrorReportSink.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BugsnagErrorReportSink.h; sourceTree = ""; }; @@ -1263,6 +1261,11 @@ 0134524A256BCF7C0088C548 /* BugsnagError+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagError+Private.h"; sourceTree = ""; }; 0134524B256BD00A0088C548 /* BugsnagThread+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagThread+Private.h"; sourceTree = ""; }; 0140D24725765F8F00FD0306 /* BSGUIKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BSGUIKit.h; sourceTree = ""; }; + 016875C4258D003200DFFF69 /* NSUserDefaultsStub.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = NSUserDefaultsStub.h; sourceTree = ""; }; + 016875C5258D003200DFFF69 /* NSUserDefaultsStub.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NSUserDefaultsStub.m; sourceTree = ""; }; + 01468F5025876DC1002B0519 /* BSGNotificationBreadcrumbs.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BSGNotificationBreadcrumbs.h; sourceTree = ""; }; + 01468F5125876DC1002B0519 /* BSGNotificationBreadcrumbs.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BSGNotificationBreadcrumbs.m; sourceTree = ""; }; + 0163BF5825823D8D008DC28B /* NotificationBreadcrumbTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = NotificationBreadcrumbTests.m; sourceTree = ""; }; 01937CF9257A7B4C00F2DE31 /* Bugsnag+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Bugsnag+Private.h"; sourceTree = ""; }; 01937D01257A7E0E00F2DE31 /* BugsnagErrorReportSink+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagErrorReportSink+Private.h"; sourceTree = ""; }; 01937D09257A7ED000F2DE31 /* BugsnagSessionTracker+Private.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "BugsnagSessionTracker+Private.h"; sourceTree = ""; }; @@ -1540,7 +1543,7 @@ 008969282486DAD000DC48C2 /* BSG_KSMach.h */, 008969112486DAD000DC48C2 /* BSG_KSMachApple.h */, 008969232486DAD000DC48C2 /* BSG_KSMachHeaders.h */, - 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.m */, + 008969102486DAD000DC48C2 /* BSG_KSMachHeaders.c */, 008969252486DAD000DC48C2 /* BSG_KSObjC.c */, 0089690F2486DAD000DC48C2 /* BSG_KSObjC.h */, 008969202486DAD000DC48C2 /* BSG_KSObjCApple.h */, @@ -1618,8 +1621,6 @@ 01937D09257A7ED000F2DE31 /* BugsnagSessionTracker+Private.h */, CBB0928B2519F891007698BC /* BugsnagSystemState.h */, CBB0928A2519F891007698BC /* BugsnagSystemState.m */, - 00AD1EF42486A17600A27979 /* RegisterErrorData.h */, - 00AD1EF52486A17600A27979 /* RegisterErrorData.m */, 00AD1CF124869EBD00A27979 /* Breadcrumbs */, 00AD1CF224869ECF00A27979 /* Client */, 00AD1CF324869ED700A27979 /* Configuration */, @@ -1685,7 +1686,9 @@ E701FAAA2490EFD9008D842F /* EventApiValidationTest.m */, 00E636C324878FFC006CBF1A /* Info.plist */, 008966D32486D43700DC48C2 /* KSCrash */, - 008966A92486D43400DC48C2 /* RegisterErrorDataTest.m */, + 016875C4258D003200DFFF69 /* NSUserDefaultsStub.h */, + 016875C5258D003200DFFF69 /* NSUserDefaultsStub.m */, + 0163BF5825823D8D008DC28B /* NotificationBreadcrumbTests.m */, 01B14C55251CE55F00118748 /* report-react-native-promise-rejection.json */, 008966B72486D43500DC48C2 /* report.json */, 008966AE2486D43500DC48C2 /* Swift Tests */, @@ -1701,6 +1704,8 @@ 00AD1CF124869EBD00A27979 /* Breadcrumbs */ = { isa = PBXGroup; children = ( + 01468F5025876DC1002B0519 /* BSGNotificationBreadcrumbs.h */, + 01468F5125876DC1002B0519 /* BSGNotificationBreadcrumbs.m */, 008967B32486D9D700DC48C2 /* BugsnagBreadcrumbs.h */, 008967B22486D9D700DC48C2 /* BugsnagBreadcrumbs.m */, ); @@ -1995,7 +2000,7 @@ 008969962486DAD100DC48C2 /* BSG_KSBacktrace_Private.h in Headers */, 00896A112486DAD100DC48C2 /* BSG_KSCrashSentry_CPPException.h in Headers */, 008969ED2486DAD100DC48C2 /* BSG_KSCrashDoctor.h in Headers */, - 00AD1F022486A17900A27979 /* RegisterErrorData.h in Headers */, + 01468F5225876DC1002B0519 /* BSGNotificationBreadcrumbs.h in Headers */, 008968ED2486DAB800DC48C2 /* BugsnagFileStore.h in Headers */, 00896A292486DAD100DC48C2 /* BSG_KSCrashType.h in Headers */, 008969DB2486DAD100DC48C2 /* BSG_KSCrash.h in Headers */, @@ -2091,7 +2096,7 @@ 008969972486DAD100DC48C2 /* BSG_KSBacktrace_Private.h in Headers */, 00896A122486DAD100DC48C2 /* BSG_KSCrashSentry_CPPException.h in Headers */, 008969EE2486DAD100DC48C2 /* BSG_KSCrashDoctor.h in Headers */, - 00AD1F032486A17900A27979 /* RegisterErrorData.h in Headers */, + 01468F5325876DC1002B0519 /* BSGNotificationBreadcrumbs.h in Headers */, 008968EE2486DAB800DC48C2 /* BugsnagFileStore.h in Headers */, 00896A2A2486DAD100DC48C2 /* BSG_KSCrashType.h in Headers */, 008969DC2486DAD100DC48C2 /* BSG_KSCrash.h in Headers */, @@ -2188,7 +2193,7 @@ 008969982486DAD100DC48C2 /* BSG_KSBacktrace_Private.h in Headers */, 00896A132486DAD100DC48C2 /* BSG_KSCrashSentry_CPPException.h in Headers */, 008969EF2486DAD100DC48C2 /* BSG_KSCrashDoctor.h in Headers */, - 00AD1F042486A17900A27979 /* RegisterErrorData.h in Headers */, + 01468F5425876DC1002B0519 /* BSGNotificationBreadcrumbs.h in Headers */, 008968EF2486DAB800DC48C2 /* BugsnagFileStore.h in Headers */, 00896A2B2486DAD100DC48C2 /* BSG_KSCrashType.h in Headers */, 008969DD2486DAD100DC48C2 /* BSG_KSCrash.h in Headers */, @@ -2456,7 +2461,7 @@ 008969992486DAD100DC48C2 /* BSG_KSMach_Arm64.c in Sources */, 008967E82486DA2D00DC48C2 /* BugsnagErrorTypes.m in Sources */, 008968722486DA9500DC48C2 /* BugsnagDevice.m in Sources */, - 008969842486DAD100DC48C2 /* BSG_KSMachHeaders.m in Sources */, + 008969842486DAD100DC48C2 /* BSG_KSMachHeaders.c in Sources */, 00896A322486DAD100DC48C2 /* BSG_KSCrashC.c in Sources */, 008969902486DAD100DC48C2 /* BSG_RFC3339DateTool.m in Sources */, 008968AB2486DA9600DC48C2 /* BugsnagStateEvent.m in Sources */, @@ -2489,6 +2494,7 @@ 008969572486DAD000DC48C2 /* BSG_KSCrashDoctor.m in Sources */, 008968B92486DA9600DC48C2 /* BugsnagStacktrace.m in Sources */, 00896A142486DAD100DC48C2 /* BSG_KSCrashSentry_Signal.c in Sources */, + 01468F5525876DC1002B0519 /* BSGNotificationBreadcrumbs.m in Sources */, 008967BE2486DA1900DC48C2 /* BugsnagClient.m in Sources */, 008968952486DA9600DC48C2 /* BugsnagHandledState.m in Sources */, 008969C32486DAD100DC48C2 /* BSG_KSObjC.c in Sources */, @@ -2507,7 +2513,6 @@ 008968C32486DA9600DC48C2 /* BugsnagUser.m in Sources */, CBAB4DD82510D2460092CBAA /* BugsnagKVStoreObjC.m in Sources */, 008968A72486DA9600DC48C2 /* BugsnagSession.m in Sources */, - 00AD1F052486A17900A27979 /* RegisterErrorData.m in Sources */, 0089683A2486DA6C00DC48C2 /* BugsnagMetadata.m in Sources */, 008969F62486DAD100DC48C2 /* BSG_KSCrash.m in Sources */, 0089695D2486DAD000DC48C2 /* BSG_KSMach_x86_32.c in Sources */, @@ -2563,6 +2568,7 @@ 0089676F2486D43700DC48C2 /* NSError+SimpleConstructor_Tests.m in Sources */, 008966F42486D43700DC48C2 /* BugsnagThreadTest.m in Sources */, 008967692486D43700DC48C2 /* BugsnagSessionTrackerTest.m in Sources */, + 016875C6258D003200DFFF69 /* NSUserDefaultsStub.m in Sources */, 008967842486D43700DC48C2 /* KSDynamicLinker_Tests.m in Sources */, 008967032486D43700DC48C2 /* BugsnagThreadSerializationTest.m in Sources */, 0089674B2486D43700DC48C2 /* BSGConnectivityTest.m in Sources */, @@ -2584,12 +2590,12 @@ 008967332486D43700DC48C2 /* BugsnagClientTests.m in Sources */, 004E353F2487B3BD007FBAE4 /* BugsnagSwiftConfigurationTests.swift in Sources */, 008967542486D43700DC48C2 /* BugsnagOnCrashTest.m in Sources */, - 008966F72486D43700DC48C2 /* RegisterErrorDataTest.m in Sources */, 008967152486D43700DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m in Sources */, 01E8765E256684E700F4B70A /* URLSessionMock.m in Sources */, 008967AB2486D43700DC48C2 /* KSMach_Tests.m in Sources */, 0089672A2486D43700DC48C2 /* BugsnagStacktraceTest.m in Sources */, 0089678D2486D43700DC48C2 /* KSCrashReportConverter_Tests.m in Sources */, + 0163BF5925823D8D008DC28B /* NotificationBreadcrumbTests.m in Sources */, 008967392486D43700DC48C2 /* BugsnagEventFromKSCrashReportTest.m in Sources */, 008967182486D43700DC48C2 /* BugsnagErrorTest.m in Sources */, 008967212486D43700DC48C2 /* BugsnagErrorReportSinkTests.m in Sources */, @@ -2617,7 +2623,7 @@ 0089699A2486DAD100DC48C2 /* BSG_KSMach_Arm64.c in Sources */, 008967E92486DA2D00DC48C2 /* BugsnagErrorTypes.m in Sources */, 008968732486DA9500DC48C2 /* BugsnagDevice.m in Sources */, - 008969852486DAD100DC48C2 /* BSG_KSMachHeaders.m in Sources */, + 008969852486DAD100DC48C2 /* BSG_KSMachHeaders.c in Sources */, 00896A332486DAD100DC48C2 /* BSG_KSCrashC.c in Sources */, 008969912486DAD100DC48C2 /* BSG_RFC3339DateTool.m in Sources */, 008968AC2486DA9600DC48C2 /* BugsnagStateEvent.m in Sources */, @@ -2651,6 +2657,7 @@ 008969582486DAD000DC48C2 /* BSG_KSCrashDoctor.m in Sources */, 008968BA2486DA9600DC48C2 /* BugsnagStacktrace.m in Sources */, 00896A152486DAD100DC48C2 /* BSG_KSCrashSentry_Signal.c in Sources */, + 01468F5625876DC1002B0519 /* BSGNotificationBreadcrumbs.m in Sources */, 008967BF2486DA1900DC48C2 /* BugsnagClient.m in Sources */, 008968962486DA9600DC48C2 /* BugsnagHandledState.m in Sources */, 008969C42486DAD100DC48C2 /* BSG_KSObjC.c in Sources */, @@ -2669,7 +2676,6 @@ 008968C42486DA9600DC48C2 /* BugsnagUser.m in Sources */, CBAB4DD92510D2460092CBAA /* BugsnagKVStoreObjC.m in Sources */, 008968A82486DA9600DC48C2 /* BugsnagSession.m in Sources */, - 00AD1F062486A17900A27979 /* RegisterErrorData.m in Sources */, 0089683B2486DA6C00DC48C2 /* BugsnagMetadata.m in Sources */, 008969F72486DAD100DC48C2 /* BSG_KSCrash.m in Sources */, 0089695E2486DAD000DC48C2 /* BSG_KSMach_x86_32.c in Sources */, @@ -2707,7 +2713,6 @@ 0089679A2486D43700DC48C2 /* FileBasedTestCase.m in Sources */, 008967912486D43700DC48C2 /* KSJSONCodec_Tests.m in Sources */, 008967732486D43700DC48C2 /* KSSysCtl_Tests.m in Sources */, - 008966F82486D43700DC48C2 /* RegisterErrorDataTest.m in Sources */, E701FAAC2490EFD9008D842F /* EventApiValidationTest.m in Sources */, 0089674F2486D43700DC48C2 /* BugsnagPluginTest.m in Sources */, 008967132486D43700DC48C2 /* BugsnagEventTests.m in Sources */, @@ -2717,6 +2722,7 @@ 008967A62486D43700DC48C2 /* KSString_Tests.m in Sources */, 004E353D2487B3B8007FBAE4 /* BugsnagSwiftTests.swift in Sources */, 008967192486D43700DC48C2 /* BugsnagErrorTest.m in Sources */, + 016875C7258D003200DFFF69 /* NSUserDefaultsStub.m in Sources */, 008967162486D43700DC48C2 /* BugsnagCollectionsBSGDictMergeTest.m in Sources */, 008967582486D43700DC48C2 /* BugsnagClientMirrorTest.m in Sources */, 0089676A2486D43700DC48C2 /* BugsnagSessionTrackerTest.m in Sources */, @@ -2733,6 +2739,7 @@ 008967702486D43700DC48C2 /* NSError+SimpleConstructor_Tests.m in Sources */, 0089671C2486D43700DC48C2 /* BugsnagSessionTest.m in Sources */, 008967AC2486D43700DC48C2 /* KSMach_Tests.m in Sources */, + 0163BF5A25823D8D008DC28B /* NotificationBreadcrumbTests.m in Sources */, 00896A452486DBF000DC48C2 /* BugsnagConfigurationTests.m in Sources */, 008967492486D43700DC48C2 /* BugsnagUserTest.m in Sources */, 0089673A2486D43700DC48C2 /* BugsnagEventFromKSCrashReportTest.m in Sources */, @@ -2777,7 +2784,7 @@ 0089699B2486DAD100DC48C2 /* BSG_KSMach_Arm64.c in Sources */, 008967EA2486DA2D00DC48C2 /* BugsnagErrorTypes.m in Sources */, 008968742486DA9500DC48C2 /* BugsnagDevice.m in Sources */, - 008969862486DAD100DC48C2 /* BSG_KSMachHeaders.m in Sources */, + 008969862486DAD100DC48C2 /* BSG_KSMachHeaders.c in Sources */, 00896A342486DAD100DC48C2 /* BSG_KSCrashC.c in Sources */, 008969922486DAD100DC48C2 /* BSG_RFC3339DateTool.m in Sources */, 008968AD2486DA9600DC48C2 /* BugsnagStateEvent.m in Sources */, @@ -2811,6 +2818,7 @@ 008969592486DAD000DC48C2 /* BSG_KSCrashDoctor.m in Sources */, 008968BB2486DA9600DC48C2 /* BugsnagStacktrace.m in Sources */, 00896A162486DAD100DC48C2 /* BSG_KSCrashSentry_Signal.c in Sources */, + 01468F5725876DC1002B0519 /* BSGNotificationBreadcrumbs.m in Sources */, 008967C02486DA1900DC48C2 /* BugsnagClient.m in Sources */, 008968972486DA9600DC48C2 /* BugsnagHandledState.m in Sources */, 008969C52486DAD100DC48C2 /* BSG_KSObjC.c in Sources */, @@ -2829,7 +2837,6 @@ 008968C52486DA9600DC48C2 /* BugsnagUser.m in Sources */, CBAB4DDA2510D2460092CBAA /* BugsnagKVStoreObjC.m in Sources */, 008968A92486DA9600DC48C2 /* BugsnagSession.m in Sources */, - 00AD1F072486A17900A27979 /* RegisterErrorData.m in Sources */, 0089683C2486DA6C00DC48C2 /* BugsnagMetadata.m in Sources */, 008969F82486DAD100DC48C2 /* BSG_KSCrash.m in Sources */, 0089695F2486DAD000DC48C2 /* BSG_KSMach_x86_32.c in Sources */, @@ -2864,7 +2871,6 @@ CB10E541250BA8E000AF5824 /* BugsnagKVStoreTest.m in Sources */, 008967922486D43700DC48C2 /* KSJSONCodec_Tests.m in Sources */, 008967742486D43700DC48C2 /* KSSysCtl_Tests.m in Sources */, - 008966F92486D43700DC48C2 /* RegisterErrorDataTest.m in Sources */, 008967502486D43700DC48C2 /* BugsnagPluginTest.m in Sources */, 008967142486D43700DC48C2 /* BugsnagEventTests.m in Sources */, 0089675C2486D43700DC48C2 /* BugsnagEnabledBreadcrumbTest.m in Sources */, @@ -2907,6 +2913,7 @@ E701FAB12490EFE8008D842F /* ConfigurationApiValidationTest.m in Sources */, 0089677D2486D43700DC48C2 /* RFC3339DateTool_Tests.m in Sources */, CBCF77AD250142E0004AF22A /* BSGJSONSerializerTest.m in Sources */, + 0163BF5B25823D8D008DC28B /* NotificationBreadcrumbTests.m in Sources */, 008967562486D43700DC48C2 /* BugsnagOnCrashTest.m in Sources */, 008967A12486D43700DC48C2 /* KSCrashSentry_Tests.m in Sources */, 008967442486D43700DC48C2 /* BugsnagSessionTrackerStopTest.m in Sources */, @@ -2915,6 +2922,7 @@ 008967322486D43700DC48C2 /* BugsnagStateEventTest.m in Sources */, CBA2249D251E429C00B87416 /* TestSupport.m in Sources */, 004E35372487AFF2007FBAE4 /* BugsnagHandledStateTest.m in Sources */, + 016875C8258D003200DFFF69 /* NSUserDefaultsStub.m in Sources */, 0089678C2486D43700DC48C2 /* KSCrashReportStore_Tests.m in Sources */, 01C17AE92542ED7F00C102C9 /* KSCrashReportWriterTests.m in Sources */, 00896A422486DBDD00DC48C2 /* BSGConfigurationBuilderTests.m in Sources */, @@ -2956,7 +2964,7 @@ E746291C248907E500F92D67 /* BSG_KSCrashC.c in Sources */, E74628FC248907C100F92D67 /* BSG_KSCrashDoctor.m in Sources */, E74628FD248907C100F92D67 /* BSG_KSJSONCodecObjC.m in Sources */, - E74628FF248907C100F92D67 /* BSG_KSMachHeaders.m in Sources */, + E74628FF248907C100F92D67 /* BSG_KSMachHeaders.c in Sources */, E7462900248907C100F92D67 /* NSError+BSG_SimpleConstructor.m in Sources */, E7462901248907C100F92D67 /* BSG_KSLogger.m in Sources */, E7462902248907C100F92D67 /* BSG_KSCrashState.m in Sources */, @@ -2973,6 +2981,7 @@ 0089687F2486DA9600DC48C2 /* BugsnagBreadcrumb.m in Sources */, 008968012486DA4500DC48C2 /* BugsnagSessionTrackingApiClient.m in Sources */, 008968322486DA5600DC48C2 /* BugsnagCollections.m in Sources */, + 01468F5825876DC1002B0519 /* BSGNotificationBreadcrumbs.m in Sources */, 008968832486DA9600DC48C2 /* BugsnagAppWithState.m in Sources */, 008968AA2486DA9600DC48C2 /* BugsnagSession.m in Sources */, 008968982486DA9600DC48C2 /* BugsnagHandledState.m in Sources */, @@ -3004,7 +3013,6 @@ 008968942486DA9600DC48C2 /* BugsnagError.m in Sources */, 008967E12486DA2D00DC48C2 /* BSGConfigurationBuilder.m in Sources */, 008967FD2486DA4500DC48C2 /* BugsnagApiClient.m in Sources */, - 00AD1F082486A17900A27979 /* RegisterErrorData.m in Sources */, 008968EC2486DAB800DC48C2 /* BugsnagSessionFileStore.m in Sources */, 008968F32486DAB800DC48C2 /* BugsnagFileStore.m in Sources */, ); diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Breadcrumbs/BSGNotificationBreadcrumbs.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Breadcrumbs/BSGNotificationBreadcrumbs.h new file mode 100644 index 0000000000..074dd3e247 --- /dev/null +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Breadcrumbs/BSGNotificationBreadcrumbs.h @@ -0,0 +1,57 @@ +// +// BSGBreadcrumbsProducer.h +// Bugsnag +// +// Created by Nick Dowell on 10/12/2020. +// Copyright © 2020 Bugsnag Inc. All rights reserved. +// + +#import + +@class BugsnagConfiguration; + +NS_ASSUME_NONNULL_BEGIN + +@protocol BSGBreadcrumbSink + +- (void)leaveBreadcrumbWithMessage:(NSString *)message metadata:(nullable NSDictionary *)metadata andType:(BSGBreadcrumbType)type; + +@end + + +#pragma mark - + +extern NSString * const BSGNotificationBreadcrumbsMessageAppWillTerminate; + +@interface BSGNotificationBreadcrumbs : NSObject + +#pragma mark Initializers + +- (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration + breadcrumbSink:(id)breadcrumbSink NS_DESIGNATED_INITIALIZER; + +- (instancetype)init UNAVAILABLE_ATTRIBUTE; + +#pragma mark Properties + +@property BugsnagConfiguration *configuration; + +@property (weak) id breadcrumbSink; + +@property NSNotificationCenter *notificationCenter; + +@property NSNotificationCenter *workspaceNotificationCenter; + +#pragma mark Methods + +/// Starts observing the default notifications. +- (void)start; + +/// Starts observing notifications with the given name and adds a "state" breadcrumbs when received. +- (void)startListeningForStateChangeNotification:(NSNotificationName)notificationName; + +- (NSString *)messageForNotificationName:(NSNotificationName)name; + +@end + +NS_ASSUME_NONNULL_END diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Breadcrumbs/BSGNotificationBreadcrumbs.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Breadcrumbs/BSGNotificationBreadcrumbs.m new file mode 100644 index 0000000000..194cf153f6 --- /dev/null +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Breadcrumbs/BSGNotificationBreadcrumbs.m @@ -0,0 +1,303 @@ +// +// BSGNotificationBreadcrumbs.m +// Bugsnag +// +// Created by Nick Dowell on 10/12/2020. +// Copyright © 2020 Bugsnag Inc. All rights reserved. +// + +#import "BSGNotificationBreadcrumbs.h" + +#import "BugsnagBreadcrumbs.h" +#import "BugsnagConfiguration+Private.h" +#import "BugsnagKeys.h" + +#if TARGET_OS_IOS || TARGET_OS_TV +#import "BSGUIKit.h" +#else +#import +#endif + + +NSString * const BSGNotificationBreadcrumbsMessageAppWillTerminate = @"App Will Terminate"; + + +@interface BSGNotificationBreadcrumbs () + +@property NSDictionary *notificationNameMap; + +@end + + +@implementation BSGNotificationBreadcrumbs + +- (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration + breadcrumbSink:(id)breadcrumbSink { + if ((self = [super init])) { + _configuration = configuration; + _notificationCenter = NSNotificationCenter.defaultCenter; +#if TARGET_OS_OSX + _workspaceNotificationCenter = NSWorkspace.sharedWorkspace.notificationCenter; +#endif + _breadcrumbSink = breadcrumbSink; + _notificationNameMap = @{ +#if TARGET_OS_TV + NSUndoManagerDidRedoChangeNotification : @"Redo Operation", + NSUndoManagerDidUndoChangeNotification : @"Undo Operation", + UIScreenBrightnessDidChangeNotification : @"Screen Brightness Changed", + UITableViewSelectionDidChangeNotification : @"TableView Select Change", + UIWindowDidBecomeHiddenNotification : @"Window Became Hidden", + UIWindowDidBecomeKeyNotification : @"Window Became Key", + UIWindowDidBecomeVisibleNotification : @"Window Became Visible", + UIWindowDidResignKeyNotification : @"Window Resigned Key", +#elif TARGET_OS_IOS + NSUndoManagerDidRedoChangeNotification : @"Redo Operation", + NSUndoManagerDidUndoChangeNotification : @"Undo Operation", + UIApplicationDidEnterBackgroundNotification : @"App Did Enter Background", + UIApplicationDidReceiveMemoryWarningNotification : @"Memory Warning", + UIApplicationUserDidTakeScreenshotNotification : @"Took Screenshot", + UIApplicationWillEnterForegroundNotification : @"App Will Enter Foreground", + UIApplicationWillTerminateNotification : BSGNotificationBreadcrumbsMessageAppWillTerminate, + UIDeviceBatteryLevelDidChangeNotification : @"Battery Level Changed", + UIDeviceBatteryStateDidChangeNotification : @"Battery State Changed", + UIDeviceOrientationDidChangeNotification : @"Orientation Changed", + UIKeyboardDidHideNotification : @"Keyboard Became Hidden", + UIKeyboardDidShowNotification : @"Keyboard Became Visible", + UIMenuControllerDidHideMenuNotification : @"Did Hide Menu", + UIMenuControllerDidShowMenuNotification : @"Did Show Menu", + UITableViewSelectionDidChangeNotification : @"TableView Select Change", + UITextFieldTextDidBeginEditingNotification : @"Began Editing Text", + UITextFieldTextDidEndEditingNotification : @"Stopped Editing Text", + UITextViewTextDidBeginEditingNotification : @"Began Editing Text", + UITextViewTextDidEndEditingNotification : @"Stopped Editing Text", + UIWindowDidBecomeHiddenNotification : @"Window Became Hidden", + UIWindowDidBecomeVisibleNotification : @"Window Became Visible", +#elif TARGET_OS_OSX + NSUndoManagerDidRedoChangeNotification : @"Redo Operation", + NSUndoManagerDidUndoChangeNotification : @"Undo Operation", + NSApplicationDidBecomeActiveNotification : @"App Became Active", + NSApplicationDidHideNotification : @"App Did Hide", + NSApplicationDidResignActiveNotification : @"App Resigned Active", + NSApplicationDidUnhideNotification : @"App Did Unhide", + NSApplicationWillTerminateNotification : BSGNotificationBreadcrumbsMessageAppWillTerminate, + NSControlTextDidBeginEditingNotification : @"Control Text Began Edit", + NSControlTextDidEndEditingNotification : @"Control Text Ended Edit", + NSMenuWillSendActionNotification : @"Menu Will Send Action", + NSTableViewSelectionDidChangeNotification : @"TableView Select Change", + NSWindowDidBecomeKeyNotification : @"Window Became Key", + NSWindowDidEnterFullScreenNotification : @"Window Entered Full Screen", + NSWindowDidExitFullScreenNotification : @"Window Exited Full Screen", + NSWindowWillCloseNotification : @"Window Will Close", + NSWindowWillMiniaturizeNotification : @"Window Will Miniaturize", + NSWorkspaceScreensDidSleepNotification : @"Workspace Screen Slept", + NSWorkspaceScreensDidWakeNotification : @"Workspace Screen Awoke", +#endif + }; + } + return self; +} + +#if TARGET_OS_OSX +- (NSArray *)workspaceBreadcrumbStateEvents { + return @[ + NSWorkspaceScreensDidSleepNotification, + NSWorkspaceScreensDidWakeNotification + ]; +} +#endif + +- (NSArray *)automaticBreadcrumbStateEvents { +#if TARGET_OS_TV + return @[ + NSUndoManagerDidRedoChangeNotification, + NSUndoManagerDidUndoChangeNotification, + UIScreenBrightnessDidChangeNotification, + UIWindowDidBecomeHiddenNotification, + UIWindowDidBecomeKeyNotification, + UIWindowDidBecomeVisibleNotification, + UIWindowDidResignKeyNotification, + ]; +#elif TARGET_OS_IOS + return @[ + NSUndoManagerDidRedoChangeNotification, + NSUndoManagerDidUndoChangeNotification, + UIApplicationDidEnterBackgroundNotification, + UIApplicationDidReceiveMemoryWarningNotification, + UIApplicationUserDidTakeScreenshotNotification, + UIApplicationWillEnterForegroundNotification, + UIApplicationWillTerminateNotification, + UIKeyboardDidHideNotification, + UIKeyboardDidShowNotification, + UIMenuControllerDidHideMenuNotification, + UIMenuControllerDidShowMenuNotification, + UIWindowDidBecomeHiddenNotification, + UIWindowDidBecomeVisibleNotification, + ]; +#elif TARGET_OS_OSX + return @[ + NSApplicationDidBecomeActiveNotification, + NSApplicationDidResignActiveNotification, + NSApplicationDidHideNotification, + NSApplicationDidUnhideNotification, + NSApplicationWillTerminateNotification, + + NSWindowDidBecomeKeyNotification, + NSWindowDidEnterFullScreenNotification, + NSWindowDidExitFullScreenNotification, + NSWindowWillCloseNotification, + NSWindowWillMiniaturizeNotification, + ]; +#endif + return nil; +} + +- (NSArray *)automaticBreadcrumbControlEvents { +#if TARGET_OS_IOS + return @[ + UITextFieldTextDidBeginEditingNotification, + UITextFieldTextDidEndEditingNotification, + UITextViewTextDidBeginEditingNotification, + UITextViewTextDidEndEditingNotification + ]; +#elif TARGET_OS_OSX + return @[ + NSControlTextDidBeginEditingNotification, + NSControlTextDidEndEditingNotification + ]; +#endif + return nil; +} + +- (NSArray *)automaticBreadcrumbTableItemEvents { +#if TARGET_OS_IOS || TARGET_OS_TV + return @[ UITableViewSelectionDidChangeNotification ]; +#elif TARGET_OS_OSX + return @[ NSTableViewSelectionDidChangeNotification ]; +#endif + return nil; +} + +- (NSArray *)automaticBreadcrumbMenuItemEvents { +#if TARGET_OS_OSX + return @[ NSMenuWillSendActionNotification ]; +#endif + return nil; +} + +- (void)dealloc { + [_notificationCenter removeObserver:self]; +} + +#pragma mark - + +- (NSString *)messageForNotificationName:(NSNotificationName)name { + return self.notificationNameMap[name] ?: [name stringByReplacingOccurrencesOfString:@"Notification" withString:@""]; +} + +- (void)addBreadcrumbWithType:(BSGBreadcrumbType)type forNotificationName:(NSNotificationName)notificationName { + [self addBreadcrumbWithType:type forNotificationName:notificationName metadata:nil]; +} + +- (void)addBreadcrumbWithType:(BSGBreadcrumbType)type forNotificationName:(NSNotificationName)notificationName metadata:(NSDictionary *)metadata { + [self.breadcrumbSink leaveBreadcrumbWithMessage:[self messageForNotificationName:notificationName] metadata:metadata ?: @{} andType:type]; +} + +#pragma mark - + +- (void)start { + // State events + if ([_configuration shouldRecordBreadcrumbType:BSGBreadcrumbTypeState]) { + // Generic state events + for (NSNotificationName name in [self automaticBreadcrumbStateEvents]) { + [self startListeningForStateChangeNotification:name]; + } + +#if TARGET_OS_OSX + // Workspace-specific events - macOS only + for (NSNotificationName name in [self workspaceBreadcrumbStateEvents]) { + [_workspaceNotificationCenter addObserver:self + selector:@selector(addBreadcrumbForNotification:) + name:name + object:nil]; + } + + // NSMenu events (macOS only) + for (NSNotificationName name in [self automaticBreadcrumbMenuItemEvents]) { + [_notificationCenter addObserver:self + selector:@selector(addBreadcrumbForMenuItemNotification:) + name:name + object:nil]; + } +#endif + } + + // Navigation events + if ([_configuration shouldRecordBreadcrumbType:BSGBreadcrumbTypeNavigation]) { + // UI/NSTableView events + for (NSNotificationName name in [self automaticBreadcrumbTableItemEvents]) { + [_notificationCenter addObserver:self + selector:@selector(addBreadcrumbForTableViewNotification:) + name:name + object:nil]; + } + } + + // User events + if ([_configuration shouldRecordBreadcrumbType:BSGBreadcrumbTypeUser]) { + // UITextField/NSControl events (text editing) + for (NSNotificationName name in [self automaticBreadcrumbControlEvents]) { + [_notificationCenter addObserver:self + selector:@selector(addBreadcrumbForControlNotification:) + name:name + object:nil]; + } + } +} + +- (void)startListeningForStateChangeNotification:(NSNotificationName)notificationName { + [_notificationCenter addObserver:self selector:@selector(addBreadcrumbForNotification:) name:notificationName object:nil]; +} + +- (void)addBreadcrumbForNotification:(NSNotification *)notification { + [self addBreadcrumbWithType:BSGBreadcrumbTypeState forNotificationName:notification.name]; +} + +- (void)addBreadcrumbForTableViewNotification:(NSNotification *)notification { +#if TARGET_OS_IOS || TARGET_OS_TV + NSIndexPath *indexPath = ((UITableView *)notification.object).indexPathForSelectedRow; + [self addBreadcrumbWithType:BSGBreadcrumbTypeNavigation forNotificationName:notification.name metadata: + indexPath ? @{@"row" : @(indexPath.row), @"section" : @(indexPath.section)} : nil]; +#elif TARGET_OS_OSX + NSTableView *tableView = notification.object; + [self addBreadcrumbWithType:BSGBreadcrumbTypeNavigation forNotificationName:notification.name metadata: + tableView ? @{@"selectedRow" : @(tableView.selectedRow), @"selectedColumn" : @(tableView.selectedColumn)} : nil]; +#endif +} + +- (void)addBreadcrumbForMenuItemNotification:(NSNotification *)notification { +#if TARGET_OS_OSX + NSMenuItem *menuItem = [[notification userInfo] valueForKey:@"MenuItem"]; + [self addBreadcrumbWithType:BSGBreadcrumbTypeState forNotificationName:notification.name metadata: + [menuItem isKindOfClass:[NSMenuItem class]] ? @{BSGKeyAction : menuItem.title} : nil]; +#endif +} + +- (void)addBreadcrumbForControlNotification:(NSNotification *)notification { +#if TARGET_OS_IOS + NSString *label = ((UIControl *)notification.object).accessibilityLabel; + [self addBreadcrumbWithType:BSGBreadcrumbTypeUser forNotificationName:notification.name metadata: + label.length ? @{BSGKeyLabel : label} : nil]; +#elif TARGET_OS_OSX + NSControl *control = notification.object; + NSDictionary *metadata = nil; + if ([control respondsToSelector:@selector(accessibilityLabel)]) { + NSString *label = control.accessibilityLabel; + if (label.length > 0) { + metadata = @{BSGKeyLabel : label}; + } + } + [self addBreadcrumbWithType:BSGBreadcrumbTypeUser forNotificationName:notification.name metadata:metadata]; +#endif +} + +@end diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagCrashSentry.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagCrashSentry.h index 129f5dd8a4..863f02958b 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagCrashSentry.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagCrashSentry.h @@ -12,10 +12,13 @@ #import "BugsnagConfiguration.h" #import "BugsnagErrorReportApiClient.h" +@class BugsnagNotifier; + @interface BugsnagCrashSentry : NSObject - (void)install:(BugsnagConfiguration *)config apiClient:(BugsnagErrorReportApiClient *)apiClient + notifier:(BugsnagNotifier *)notifier onCrash:(BSGReportCallback)onCrash; - (void)reportUserException:(NSString *)reportName diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagCrashSentry.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagCrashSentry.m index 7e779faf3d..1b5d05e5a6 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagCrashSentry.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagCrashSentry.m @@ -16,20 +16,19 @@ #import "Bugsnag.h" #import "BugsnagErrorTypes.h" -NSUInteger const BSG_MAX_STORED_REPORTS = 12; - @implementation BugsnagCrashSentry - (void)install:(BugsnagConfiguration *)config apiClient:(BugsnagErrorReportApiClient *)apiClient + notifier:(BugsnagNotifier *)notifier onCrash:(BSGReportCallback)onCrash { - BugsnagErrorReportSink *sink = [[BugsnagErrorReportSink alloc] initWithApiClient:apiClient]; + BugsnagErrorReportSink *sink = [[BugsnagErrorReportSink alloc] initWithApiClient:apiClient configuration:config notifier:notifier]; BSG_KSCrash *ksCrash = [BSG_KSCrash sharedInstance]; ksCrash.sink = sink; - ksCrash.introspectMemory = YES; + ksCrash.introspectMemory = NO; ksCrash.onCrash = onCrash; - ksCrash.maxStoredReports = BSG_MAX_STORED_REPORTS; + ksCrash.maxStoredReports = (int)config.maxPersistedEvents; // overridden elsewhere for handled errors, so we can assume that this only // applies to unhandled errors diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink+Private.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink+Private.h index 306c06ac5c..1a4994be81 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink+Private.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink+Private.h @@ -8,6 +8,8 @@ #import "BugsnagErrorReportSink.h" +@class BugsnagEvent; + NS_ASSUME_NONNULL_BEGIN @interface BugsnagErrorReportSink () diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink.h index 966ff928a8..2339e1bb84 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink.h @@ -25,16 +25,26 @@ // #import -#import "BSG_KSCrash.h" -#import "BugsnagErrorReportApiClient.h" + +#import "BSGOnErrorSentBlock.h" + +@class BugsnagConfiguration; +@class BugsnagErrorReportApiClient; +@class BugsnagNotifier; NS_ASSUME_NONNULL_BEGIN @interface BugsnagErrorReportSink : NSObject -@property(nonatomic, strong) BugsnagErrorReportApiClient *apiClient; +- (instancetype)initWithApiClient:(BugsnagErrorReportApiClient *)apiClient + configuration:(BugsnagConfiguration *)configuration + notifier:(BugsnagNotifier *)notifier; + +@property (strong, nonatomic) BugsnagErrorReportApiClient *apiClient; + +@property (strong, nonatomic) BugsnagConfiguration *configuration; -- (instancetype)initWithApiClient:(BugsnagErrorReportApiClient *)apiClient; +@property (strong, nonatomic) BugsnagNotifier *notifier; /** * Invoked when reports stored by KSCrash need to be delivered. diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink.m index 555d764a0c..60a21423cd 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagErrorReportSink.m @@ -31,6 +31,7 @@ #import "BugsnagClient+Private.h" #import "BugsnagCollections.h" #import "BugsnagConfiguration+Private.h" +#import "BugsnagErrorReportApiClient.h" #import "BugsnagEvent+Private.h" #import "BugsnagKeys.h" #import "BugsnagLogger.h" @@ -42,10 +43,14 @@ @interface BugsnagErrorReportSink () @implementation BugsnagErrorReportSink -- (instancetype)initWithApiClient:(BugsnagErrorReportApiClient *)apiClient { - if (self = [super init]) { - self.apiClient = apiClient; - self.activeRequests = [NSMutableSet new]; +- (instancetype)initWithApiClient:(BugsnagErrorReportApiClient *)apiClient + configuration:(BugsnagConfiguration *)configuration + notifier:(BugsnagNotifier *)notifier { + if ((self = [super init])) { + _apiClient = apiClient; + _activeRequests = [NSMutableSet new]; + _configuration = configuration; + _notifier = notifier; } return self; } @@ -86,7 +91,6 @@ - (void)sendStoredReports:(NSDictionary *)ksCrashRe // 4. When a request has completed and deleted the file, remove the files from the dictionary NSArray *keys = [self prepareNewRequests:[ksCrashReports allKeys]]; NSMutableDictionary* storedEvents = [NSMutableDictionary new]; - BugsnagConfiguration *configuration = [Bugsnag configuration]; // run user callbacks on events before enqueueing any requests, as // this way events can be discarded quickly. This frees up disk @@ -94,28 +98,33 @@ - (void)sendStoredReports:(NSDictionary *)ksCrashRe for (NSString *fileKey in keys) { NSDictionary *report = ksCrashReports[fileKey]; BugsnagEvent *event = [[BugsnagEvent alloc] initWithKSReport:report]; - event.redactedKeys = configuration.redactedKeys; - - if ([event shouldBeSent] && [self runOnSendBlocks:configuration event:event]) { + event.redactedKeys = self.configuration.redactedKeys; + + NSString *errorClass = event.errors.firstObject.errorClass; + if ([self.configuration shouldDiscardErrorClass:errorClass]) { + bsg_log_info(@"Discarding event because errorClass \"%@\" matched configuration.discardClasses", errorClass); + [self finishActiveRequest:fileKey completed:YES error:nil block:block]; + continue; + } + + if (self.configuration.shouldSendReports && [event shouldBeSent] && [self runOnSendBlocksForEvent:event]) { storedEvents[fileKey] = event; } else { // delete the report as the user has discarded it [self finishActiveRequest:fileKey completed:YES error:nil block:block]; } } - [self deliverStoredEvents:storedEvents configuration:configuration block:block]; + [self deliverStoredEvents:storedEvents block:block]; } -- (void)deliverStoredEvents:(NSMutableDictionary *)storedEvents - configuration:(BugsnagConfiguration *)configuration - block:(BSGOnErrorSentBlock)block { +- (void)deliverStoredEvents:(NSMutableDictionary *)storedEvents block:(BSGOnErrorSentBlock)block { for (NSString *filename in storedEvents) { BugsnagEvent *event = storedEvents[filename]; NSDictionary *requestPayload = [self prepareEventPayload:event]; - NSMutableDictionary *apiHeaders = [[configuration errorApiHeaders] mutableCopy]; + NSMutableDictionary *apiHeaders = [self.configuration.errorApiHeaders mutableCopy]; apiHeaders[BugsnagHTTPHeaderNameApiKey] = event.apiKey; apiHeaders[BugsnagHTTPHeaderNameStacktraceTypes] = [event.stacktraceTypes componentsJoinedByString:@","]; - [self.apiClient sendJSONPayload:requestPayload headers:apiHeaders toURL:configuration.notifyURL + [self.apiClient sendJSONPayload:requestPayload headers:apiHeaders toURL:self.configuration.notifyURL completionHandler:^(BugsnagApiClientDeliveryStatus status, NSError *error) { BOOL completed = status == BugsnagApiClientDeliveryStatusDelivered || status == BugsnagApiClientDeliveryStatusUndeliverable; [self finishActiveRequest:filename completed:completed error:error block:block]; @@ -123,9 +132,8 @@ - (void)deliverStoredEvents:(NSMutableDictionary *)s } } -- (BOOL)runOnSendBlocks:(BugsnagConfiguration *)configuration - event:(BugsnagEvent *)event { - for (BugsnagOnSendErrorBlock onSendErrorBlock in configuration.onSendBlocks) { +- (BOOL)runOnSendBlocksForEvent:(BugsnagEvent *)event { + for (BugsnagOnSendErrorBlock onSendErrorBlock in self.configuration.onSendBlocks) { @try { if (!onSendErrorBlock(event)) { return false; @@ -143,8 +151,15 @@ - (BOOL)runOnSendBlocks:(BugsnagConfiguration *)configuration * @return an Error Reporting API payload represented as a serializable dictionary */ - (NSDictionary *)prepareEventPayload:(BugsnagEvent *)event { + if (!event.app.type) { + // Use current value for crashes from older notifier versions that didn't persist config.appType + event.app.type = self.configuration.appType; + } + if (!event.apiKey) { + event.apiKey = self.configuration.apiKey; + } NSMutableDictionary *data = [[NSMutableDictionary alloc] init]; - data[BSGKeyNotifier] = [[Bugsnag client].notifier toDict]; + data[BSGKeyNotifier] = [self.notifier toDict]; data[BSGKeyApiKey] = event.apiKey; data[BSGKeyPayloadVersion] = @"4.0"; data[BSGKeyEvents] = @[[event toJson]]; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagSessionTracker.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagSessionTracker.m index a93aee55d6..c110aed6c6 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagSessionTracker.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/BugsnagSessionTracker.m @@ -8,18 +8,17 @@ #import "BugsnagSessionTracker+Private.h" +#import "BSG_KSSystemInfo.h" #import "BugsnagApp+Private.h" -#import "BugsnagClient.h" +#import "BugsnagClient+Private.h" +#import "BugsnagCollections.h" #import "BugsnagConfiguration+Private.h" #import "BugsnagDevice+Private.h" -#import "BugsnagSessionFileStore.h" -#import "BSG_KSLogger.h" -#import "BugsnagSessionTrackingPayload.h" -#import "BugsnagSessionTrackingApiClient.h" #import "BugsnagLogger.h" #import "BugsnagSession+Private.h" -#import "BSG_KSSystemInfo.h" -#import "BugsnagCollections.h" +#import "BugsnagSessionFileStore.h" +#import "BugsnagSessionTrackingApiClient.h" +#import "BugsnagSessionTrackingPayload.h" /** Number of seconds in background required to make a new session @@ -51,14 +50,15 @@ - (instancetype)initWithConfig:(BugsnagConfiguration *)config if (self = [super init]) { _config = config; _client = client; - _apiClient = [[BugsnagSessionTrackingApiClient alloc] initWithConfig:config queueName:@"Session API queue"]; + _apiClient = [[BugsnagSessionTrackingApiClient alloc] initWithConfig:config queueName:@"Session API queue" notifier:client.notifier]; _callback = callback; NSString *storePath = [BugsnagFileStore findReportStorePath:@"Sessions"]; if (!storePath) { - BSG_KSLOG_ERROR(@"Failed to initialize session store."); + bsg_log_err(@"Failed to initialize session store."); } - _sessionStore = [BugsnagSessionFileStore storeWithPath:storePath]; + + _sessionStore = [BugsnagSessionFileStore storeWithPath:storePath maxPersistedSessions:config.maxPersistedSessions]; _extraRuntimeInfo = [NSMutableDictionary new]; } return self; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Client/BugsnagClient.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Client/BugsnagClient.m index 71ff25e808..9f1fe013fd 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Client/BugsnagClient.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Client/BugsnagClient.m @@ -31,6 +31,7 @@ #import "BSGCachesDirectory.h" #import "BSGConnectivity.h" #import "BSGJSONSerialization.h" +#import "BSGNotificationBreadcrumbs.h" #import "BSGSerialization.h" #import "BSG_KSCrash.h" #import "BSG_KSCrashC.h" @@ -101,8 +102,6 @@ void (*onCrash)(const BSG_KSCrashReportWriter *writer); } bsg_g_bugsnag_data; -static NSDictionary *notificationNameMap; - static char *sessionId[128]; static char *sessionStartDate[128]; static char *watchdogSentinelPath = NULL; @@ -154,24 +153,6 @@ void BSSerializeDataCrashHandler(const BSG_KSCrashReportWriter *writer, int type } } -/** - * Maps an NSNotificationName to its standard (Bugsnag) name - * - * @param name The NSNotificationName (type aliased to NSString) - * - * @returns The Bugsnag-standard name, or the notification name minus the "Notification" portion. - */ -NSString *BSGBreadcrumbNameForNotificationName(NSString *name) { - NSString *readableName = notificationNameMap[name]; - - if (readableName) { - return readableName; - } else { - return [name stringByReplacingOccurrencesOfString:@"Notification" - withString:@""]; - } -} - /** * Convert a device orientation into its Bugsnag string representation * @@ -242,6 +223,12 @@ void BSGWriteSessionCrashData(BugsnagSession *session) { // MARK: - BugsnagClient // ============================================================================= +@interface BugsnagClient () + +@property BSGNotificationBreadcrumbs *notificationBreadcrumbs; + +@end + @implementation BugsnagClient /** @@ -284,10 +271,7 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration { self.errorReportApiClient = [[BugsnagErrorReportApiClient alloc] initWithSession:configuration.session queueName:@"Error API queue"]; bsg_g_bugsnag_data.onCrash = (void (*)(const BSG_KSCrashReportWriter *))self.configuration.onCrashHandler; - static dispatch_once_t once_t; - dispatch_once(&once_t, ^{ - [self initializeNotificationNameMap]; - }); + _notificationBreadcrumbs = [[BSGNotificationBreadcrumbs alloc] initWithConfiguration:configuration breadcrumbSink:self]; self.sessionTracker = [[BugsnagSessionTracker alloc] initWithConfig:self.configuration client:self @@ -297,6 +281,8 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration { self.breadcrumbs = [[BugsnagBreadcrumbs alloc] initWithConfiguration:self.configuration]; + [BSGJSONSerialization writeJSONObject:configuration.dictionaryRepresentation toFile:_configMetadataFile options:0 error:nil]; + // Start with a copy of the configuration metadata self.metadata = [[configuration metadata] deepCopy]; // add metadata about app/device @@ -305,7 +291,6 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration { [self.metadata addMetadata:BSGParseDeviceMetadata(@{@"system": systemInfo}) toSection:BSGKeyDevice]; // sync initial state [self metadataChanged:self.metadata]; - [self metadataChanged:self.configuration.config]; [self metadataChanged:self.state]; // add observers for future metadata changes @@ -317,7 +302,6 @@ - (instancetype)initWithConfiguration:(BugsnagConfiguration *)configuration { [weakSelf metadataChanged:event.data]; }; [self.metadata addObserverWithBlock:observer]; - [self.configuration.config addObserverWithBlock:observer]; [self.state addObserverWithBlock:observer]; self.pluginClient = [[BugsnagPluginClient alloc] initWithPlugins:self.configuration.plugins @@ -363,86 +347,14 @@ - (void)notifyObservers:(BugsnagStateEvent *)event { } } -NSString *const kWindowVisible = @"Window Became Visible"; -NSString *const kWindowHidden = @"Window Became Hidden"; -NSString *const kBeganTextEdit = @"Began Editing Text"; -NSString *const kStoppedTextEdit = @"Stopped Editing Text"; -NSString *const kUndoOperation = @"Undo Operation"; -NSString *const kRedoOperation = @"Redo Operation"; -NSString *const kTableViewSelectionChange = @"TableView Select Change"; -NSString *const kAppWillTerminate = @"App Will Terminate"; -NSString *const BSGBreadcrumbLoadedMessage = @"Bugsnag loaded"; - -/** - * A map of notification names to human-readable strings - */ -- (void)initializeNotificationNameMap { - notificationNameMap = @{ -#if BSG_PLATFORM_TVOS - NSUndoManagerDidUndoChangeNotification : kUndoOperation, - NSUndoManagerDidRedoChangeNotification : kRedoOperation, - UIWindowDidBecomeVisibleNotification : kWindowVisible, - UIWindowDidBecomeHiddenNotification : kWindowHidden, - UIWindowDidBecomeKeyNotification : @"Window Became Key", - UIWindowDidResignKeyNotification : @"Window Resigned Key", - UIScreenBrightnessDidChangeNotification : @"Screen Brightness Changed", - UITableViewSelectionDidChangeNotification : kTableViewSelectionChange, - -#elif BSG_PLATFORM_IOS - UIWindowDidBecomeVisibleNotification : kWindowVisible, - UIWindowDidBecomeHiddenNotification : kWindowHidden, - UIApplicationWillTerminateNotification : kAppWillTerminate, - UIApplicationWillEnterForegroundNotification : @"App Will Enter Foreground", - UIApplicationDidEnterBackgroundNotification : @"App Did Enter Background", - UIKeyboardDidShowNotification : @"Keyboard Became Visible", - UIKeyboardDidHideNotification : @"Keyboard Became Hidden", - UIMenuControllerDidShowMenuNotification : @"Did Show Menu", - UIMenuControllerDidHideMenuNotification : @"Did Hide Menu", - NSUndoManagerDidUndoChangeNotification : kUndoOperation, - NSUndoManagerDidRedoChangeNotification : kRedoOperation, - UIApplicationUserDidTakeScreenshotNotification : @"Took Screenshot", - UITextFieldTextDidBeginEditingNotification : kBeganTextEdit, - UITextViewTextDidBeginEditingNotification : kBeganTextEdit, - UITextFieldTextDidEndEditingNotification : kStoppedTextEdit, - UITextViewTextDidEndEditingNotification : kStoppedTextEdit, - UITableViewSelectionDidChangeNotification : kTableViewSelectionChange, - UIDeviceBatteryStateDidChangeNotification : @"Battery State Changed", - UIDeviceBatteryLevelDidChangeNotification : @"Battery Level Changed", - UIDeviceOrientationDidChangeNotification : @"Orientation Changed", - UIApplicationDidReceiveMemoryWarningNotification : @"Memory Warning", - -#elif BSG_PLATFORM_OSX - NSApplicationDidBecomeActiveNotification : @"App Became Active", - NSApplicationDidResignActiveNotification : @"App Resigned Active", - NSApplicationDidHideNotification : @"App Did Hide", - NSApplicationDidUnhideNotification : @"App Did Unhide", - NSApplicationWillTerminateNotification : kAppWillTerminate, - NSWorkspaceScreensDidSleepNotification : @"Workspace Screen Slept", - NSWorkspaceScreensDidWakeNotification : @"Workspace Screen Awoke", - NSWindowWillCloseNotification : @"Window Will Close", - NSWindowDidBecomeKeyNotification : @"Window Became Key", - NSWindowWillMiniaturizeNotification : @"Window Will Miniaturize", - NSWindowDidEnterFullScreenNotification : @"Window Entered Full Screen", - NSWindowDidExitFullScreenNotification : @"Window Exited Full Screen", - NSControlTextDidBeginEditingNotification : @"Control Text Began Edit", - NSControlTextDidEndEditingNotification : @"Control Text Ended Edit", - NSMenuWillSendActionNotification : @"Menu Will Send Action", - NSTableViewSelectionDidChangeNotification : kTableViewSelectionChange, -#endif - }; -} - - (void)start { [self.configuration validate]; - - [self.crashSentry install:self.configuration - apiClient:self.errorReportApiClient - onCrash:&BSSerializeDataCrashHandler]; + [self.crashSentry install:self.configuration apiClient:self.errorReportApiClient notifier:self.notifier onCrash:&BSSerializeDataCrashHandler]; [self.systemState recordAppUUID]; // Needs to be called after crashSentry installed but before -computeDidCrashLastLaunch [self computeDidCrashLastLaunch]; [self.breadcrumbs removeAllBreadcrumbs]; [self setupConnectivityListener]; - [self updateAutomaticBreadcrumbDetectionSettings]; + [self.notificationBreadcrumbs start]; NSNotificationCenter *center = [NSNotificationCenter defaultCenter]; [self watchLifecycleEvents:center]; @@ -497,9 +409,7 @@ - (void)start { [self.sessionTracker startNewSessionIfAutoCaptureEnabled]; // Record a "Bugsnag Loaded" message - [self addAutoBreadcrumbOfType:BSGBreadcrumbTypeState - withMessage:BSGBreadcrumbLoadedMessage - andMetadata:nil]; + [self addAutoBreadcrumbOfType:BSGBreadcrumbTypeState withMessage:@"Bugsnag loaded" andMetadata:nil]; // notification not received in time on initial startup, so trigger manually [self willEnterForeground:self]; @@ -729,7 +639,7 @@ - (void)leaveBreadcrumbWithMessage:(NSString *_Nonnull)message { } - (void)leaveBreadcrumbForNotificationName:(NSString *_Nonnull)notificationName { - [self startListeningForStateChangeNotification:notificationName]; + [self.notificationBreadcrumbs startListeningForStateChangeNotification:notificationName]; } - (void)leaveBreadcrumbWithMessage:(NSString *_Nonnull)message @@ -883,7 +793,7 @@ - (void)notifyOutOfMemoryEvent { // If the termination breadcrumb is set, the app entered a normal // termination flow but expired before the watchdog sentinel could // be updated. In this case, no report should be sent. - if ([name isEqualToString:kAppWillTerminate]) { + if ([name isEqualToString:BSGNotificationBreadcrumbsMessageAppWillTerminate]) { return; } } @@ -964,6 +874,12 @@ - (void)notify:(NSException *)exception - (void)notifyInternal:(BugsnagEvent *_Nonnull)event block:(BugsnagOnErrorBlock)block { + NSString *errorClass = event.errors.firstObject.errorClass; + if ([self.configuration shouldDiscardErrorClass:errorClass]) { + bsg_log_info(@"Discarding event because errorClass \"%@\" matched configuration.discardClasses", errorClass); + return; + } + // enhance device information with additional metadata NSDictionary *deviceFields = [self.state getMetadataFromSection:BSGKeyDeviceState]; @@ -1004,7 +920,7 @@ - (void)notifyInternal:(BugsnagEvent *_Nonnull)event callbackOverrides:event.overrides eventOverrides:eventOverrides metadata:[event.metadata toDictionary] - config:[self.configuration.config toDictionary]]; + config:self.configuration.dictionaryRepresentation]; // A basic set of event metadata NSMutableDictionary *metadata = [@{ @@ -1057,8 +973,6 @@ - (void)metadataChanged:(BugsnagMetadata *)metadata { @synchronized(metadata) { if (metadata == self.metadata) { [BSGJSONSerialization writeJSONObject:[metadata toDictionary] toFile:self.metadataFile options:0 error:nil]; - } else if (metadata == self.configuration.config) { - [BSGJSONSerialization writeJSONObject:[metadata getMetadataFromSection:BSGKeyConfig] toFile:self.configMetadataFile options:0 error:nil]; } else if (metadata == self.state) { [BSGJSONSerialization writeJSONObject:[metadata toDictionary] toFile:self.stateMetadataFile options:0 error:nil]; } @@ -1116,7 +1030,7 @@ - (void)orientationChanged:(NSNotification *)notification { // Send a breadcrumb and preserve the orientation. [self addAutoBreadcrumbOfType:BSGBreadcrumbTypeState - withMessage:BSGBreadcrumbNameForNotificationName(notification.name) + withMessage:[self.notificationBreadcrumbs messageForNotificationName:notification.name] andMetadata:@{ @"from" : _lastOrientation, @"to" : orientation @@ -1129,11 +1043,8 @@ - (void)lowMemoryWarning:(NSNotification *)notif { [self.state addMetadata:[BSG_RFC3339DateTool stringFromDate:[NSDate date]] withKey:BSEventLowMemoryWarning toSection:BSGKeyDeviceState]; - - if ([[self configuration] shouldRecordBreadcrumbType:BSGBreadcrumbTypeState]) { - [self sendBreadcrumbForNotification:notif]; - } } + #endif /** @@ -1157,280 +1068,10 @@ - (void)addAutoBreadcrumbOfType:(BSGBreadcrumbType)breadcrumbType } } -/** - * Configure event listeners (i.e. observers) for enabled automatic breadcrumbs. - */ -- (void)updateAutomaticBreadcrumbDetectionSettings { - // State events - if ([[self configuration] shouldRecordBreadcrumbType:BSGBreadcrumbTypeState]) { - // Generic state events - for (NSString *name in [self automaticBreadcrumbStateEvents]) { - [self startListeningForStateChangeNotification:name]; - } - -#if BSG_PLATFORM_OSX - // Workspace-specific events - MacOS only - for (NSString *name in [self workspaceBreadcrumbStateEvents]) { - [self startListeningForWorkspaceStateChangeNotifications:name]; - } -#endif - - // NSMenu events (Mac only) - for (NSString *name in [self automaticBreadcrumbMenuItemEvents]) { - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(sendBreadcrumbForMenuItemNotification:) - name:name - object:nil]; - } - } - - // Navigation events - if ([[self configuration] shouldRecordBreadcrumbType:BSGBreadcrumbTypeNavigation]) { - // UI/NSTableView events - for (NSString *name in [self automaticBreadcrumbTableItemEvents]) { - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(sendBreadcrumbForTableViewNotification:) - name:name - object:nil]; - } - } - - // User events - if ([[self configuration] shouldRecordBreadcrumbType:BSGBreadcrumbTypeUser]) { - // UITextField/NSControl events (text editing) - for (NSString *name in [self automaticBreadcrumbControlEvents]) { - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(sendBreadcrumbForControlNotification:) - name:name - object:nil]; - } - } -} - -/** - * NSWorkspace-specific automatic breadcrumb events - */ -- (NSArray *)workspaceBreadcrumbStateEvents { -#if BSG_PLATFORM_OSX - return @[ - NSWorkspaceScreensDidSleepNotification, - NSWorkspaceScreensDidWakeNotification - ]; -#endif - - // Fall-through - return nil; -} - -- (NSArray *)automaticBreadcrumbStateEvents { -#if BSG_PLATFORM_TVOS - return @[ - NSUndoManagerDidUndoChangeNotification, - NSUndoManagerDidRedoChangeNotification, - UIWindowDidBecomeVisibleNotification, - UIWindowDidBecomeHiddenNotification, UIWindowDidBecomeKeyNotification, - UIWindowDidResignKeyNotification, - UIScreenBrightnessDidChangeNotification - ]; -#elif BSG_PLATFORM_IOS - return @[ - UIWindowDidBecomeHiddenNotification, - UIWindowDidBecomeVisibleNotification, - UIApplicationWillTerminateNotification, - UIApplicationWillEnterForegroundNotification, - UIApplicationDidEnterBackgroundNotification, - UIKeyboardDidShowNotification, UIKeyboardDidHideNotification, - UIMenuControllerDidShowMenuNotification, - UIMenuControllerDidHideMenuNotification, - NSUndoManagerDidUndoChangeNotification, - NSUndoManagerDidRedoChangeNotification, -#if __IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_7_0 - UIApplicationUserDidTakeScreenshotNotification -#endif - ]; -#elif BSG_PLATFORM_OSX - return @[ - NSApplicationDidBecomeActiveNotification, - NSApplicationDidResignActiveNotification, - NSApplicationDidHideNotification, - NSApplicationDidUnhideNotification, - NSApplicationWillTerminateNotification, - - NSWindowWillCloseNotification, - NSWindowDidBecomeKeyNotification, - NSWindowWillMiniaturizeNotification, - NSWindowDidEnterFullScreenNotification, - NSWindowDidExitFullScreenNotification - ]; -#endif - - // Fall-through - return nil; -} - -- (NSArray *)automaticBreadcrumbControlEvents { -#if BSG_PLATFORM_IOS - return @[ - UITextFieldTextDidBeginEditingNotification, - UITextViewTextDidBeginEditingNotification, - UITextFieldTextDidEndEditingNotification, - UITextViewTextDidEndEditingNotification - ]; -#elif BSG_PLATFORM_OSX - return @[ - NSControlTextDidBeginEditingNotification, - NSControlTextDidEndEditingNotification - ]; -#endif - - // Fall-through - return nil; -} - -- (NSArray *)automaticBreadcrumbTableItemEvents { -#if BSG_PLATFORM_IOS || BSG_PLATFORM_TVOS - return @[ UITableViewSelectionDidChangeNotification ]; -#elif BSG_PLATFORM_OSX - return @[ NSTableViewSelectionDidChangeNotification ]; -#endif - - // Fall-through - return nil; -} - -- (NSArray *)automaticBreadcrumbMenuItemEvents { -#if BSG_PLATFORM_TVOS - return @[]; -#elif BSG_PLATFORM_IOS - return nil; -#elif BSG_PLATFORM_OSX - return @[ NSMenuWillSendActionNotification ]; -#endif - - // Fall-through - return nil; -} - -/** - * Configure a generic state change breadcrumb listener - * - * @param notificationName The name of the notification. - */ -- (void)startListeningForStateChangeNotification:(NSString *)notificationName { - [[NSNotificationCenter defaultCenter] - addObserver:self - selector:@selector(sendBreadcrumbForNotification:) - name:notificationName - object:nil]; -} - -/** - * Configure an NSWorkspace-specific state change breadcrumb listener. MacOS only. - * - * @param notificationName The name of the notification. - */ -#if BSG_PLATFORM_OSX -- (void)startListeningForWorkspaceStateChangeNotifications:(NSString *)notificationName { - [NSWorkspace.sharedWorkspace.notificationCenter - addObserver:self - selector:@selector(sendBreadcrumbForNotification:) - name:notificationName - object:nil]; - } -#endif - - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (void)sendBreadcrumbForNotification:(NSNotification *)note { - [self addBreadcrumbWithBlock:^(BugsnagBreadcrumb *_Nonnull breadcrumb) { - breadcrumb.type = BSGBreadcrumbTypeState; - breadcrumb.message = BSGBreadcrumbNameForNotificationName(note.name); - }]; -} - -/** - * Leave a navigation breadcrumb whenever a tableView selection changes - * - * @param notification The UI/NSTableViewSelectionDidChangeNotification - */ -- (void)sendBreadcrumbForTableViewNotification:(NSNotification *)notification { -#if BSG_PLATFORM_IOS || BSG_PLATFORM_TVOS - UITableView *tableView = [notification object]; - NSIndexPath *indexPath = [tableView indexPathForSelectedRow]; - [self addBreadcrumbWithBlock:^(BugsnagBreadcrumb *_Nonnull breadcrumb) { - breadcrumb.type = BSGBreadcrumbTypeNavigation; - breadcrumb.message = BSGBreadcrumbNameForNotificationName(notification.name); - if (indexPath) { - breadcrumb.metadata = - @{ @"row" : @(indexPath.row), - @"section" : @(indexPath.section) }; - } - }]; -#elif BSG_PLATFORM_OSX - NSTableView *tableView = [notification object]; - [self addBreadcrumbWithBlock:^(BugsnagBreadcrumb *_Nonnull breadcrumb) { - breadcrumb.type = BSGBreadcrumbTypeNavigation; - breadcrumb.message = BSGBreadcrumbNameForNotificationName(notification.name); - if (tableView) { - breadcrumb.metadata = @{ - @"selectedRow" : @(tableView.selectedRow), - @"selectedColumn" : @(tableView.selectedColumn) - }; - } - }]; -#endif -} - -/** -* Leave a state breadcrumb whenever a tableView selection changes -* -* @param notification The UI/NSTableViewSelectionDidChangeNotification -*/ -- (void)sendBreadcrumbForMenuItemNotification:(NSNotification *)notification { -#if BSG_PLATFORM_OSX - NSMenuItem *menuItem = [[notification userInfo] valueForKey:@"MenuItem"]; - if ([menuItem isKindOfClass:[NSMenuItem class]]) { - [self addBreadcrumbWithBlock:^(BugsnagBreadcrumb *_Nonnull breadcrumb) { - breadcrumb.type = BSGBreadcrumbTypeState; - breadcrumb.message = BSGBreadcrumbNameForNotificationName(notification.name); - if (menuItem.title.length > 0) - breadcrumb.metadata = @{BSGKeyAction : menuItem.title}; - }]; - } -#endif -} - -- (void)sendBreadcrumbForControlNotification:(NSNotification *)note { -#if BSG_PLATFORM_IOS - UIControl *control = note.object; - [self addBreadcrumbWithBlock:^(BugsnagBreadcrumb *_Nonnull breadcrumb) { - breadcrumb.type = BSGBreadcrumbTypeUser; - breadcrumb.message = BSGBreadcrumbNameForNotificationName(note.name); - NSString *label = control.accessibilityLabel; - if (label.length > 0) { - breadcrumb.metadata = @{BSGKeyLabel : label}; - } - }]; -#elif BSG_PLATFORM_OSX - NSControl *control = note.object; - [self addBreadcrumbWithBlock:^(BugsnagBreadcrumb *_Nonnull breadcrumb) { - breadcrumb.type = BSGBreadcrumbTypeUser; - breadcrumb.message = BSGBreadcrumbNameForNotificationName(note.name); - if ([control respondsToSelector:@selector(accessibilityLabel)]) { - NSString *label = control.accessibilityLabel; - if (label.length > 0) { - breadcrumb.metadata = @{BSGKeyLabel : label}; - } - } - }]; -#endif -} - // MARK: - - (void)addMetadata:(NSDictionary *_Nonnull)metadata diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BSGConfigurationBuilder.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BSGConfigurationBuilder.m index d704d34e9f..52312be739 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BSGConfigurationBuilder.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BSGConfigurationBuilder.m @@ -1,9 +1,9 @@ #import "BSGConfigurationBuilder.h" -#import "BSG_KSLogger.h" #import "BugsnagConfiguration.h" #import "BugsnagEndpointConfiguration.h" #import "BugsnagKeys.h" +#import "BugsnagLogger.h" static BOOL BSGValueIsBoolean(id object) { return object != nil && [object isKindOfClass:[NSNumber class]] @@ -30,6 +30,8 @@ + (BugsnagConfiguration *)configurationFromOptions:(NSDictionary *)options { BSGKeyEnabledReleaseStages, BSGKeyEndpoints, BSGKeyMaxBreadcrumbs, + BSGKeyMaxPersistedEvents, + BSGKeyMaxPersistedSessions, BSGKeyPersistUser, BSGKeyRedactedKeys, BSGKeyReleaseStage, @@ -39,7 +41,7 @@ + (BugsnagConfiguration *)configurationFromOptions:(NSDictionary *)options { NSMutableSet *unknownKeys = [NSMutableSet setWithArray:options.allKeys]; [unknownKeys minusSet:[NSSet setWithArray:validKeys]]; if (unknownKeys.count > 0) { - BSG_KSLOG_WARN(@"Unknown dictionary keys passed in configuration options: %@", unknownKeys); + bsg_log_warn(@"Unknown dictionary keys passed in configuration options: %@", unknownKeys); } [self loadString:config options:options key:BSGKeyAppType]; @@ -54,7 +56,9 @@ + (BugsnagConfiguration *)configurationFromOptions:(NSDictionary *)options { [self loadStringArray:config options:options key:BSGKeyRedactedKeys]; [self loadEndpoints:config options:options]; - [self loadMaxBreadcrumbs:config options:options]; + [self loadNumber:config options:options key:BSGKeyMaxBreadcrumbs]; + [self loadNumber:config options:options key:BSGKeyMaxPersistedEvents]; + [self loadNumber:config options:options key:BSGKeyMaxPersistedSessions]; [self loadSendThreads:config options:options]; return config; } @@ -71,6 +75,12 @@ + (void)loadString:(BugsnagConfiguration *)config options:(NSDictionary *)option } } ++ (void)loadNumber:(BugsnagConfiguration *)config options:(NSDictionary *)options key:(NSString *)key { + if (options[key] && [options[key] isKindOfClass:[NSNumber class]]) { + [config setValue:options[key] forKey:key]; + } +} + + (void)loadStringArray:(BugsnagConfiguration *)config options:(NSDictionary *)options key:(NSString *)key { if (options[key] && [options[key] isKindOfClass:[NSArray class]]) { NSArray *val = options[key]; @@ -97,13 +107,6 @@ + (void)loadEndpoints:(BugsnagConfiguration *)config options:(NSDictionary *)opt } } -+ (void)loadMaxBreadcrumbs:(BugsnagConfiguration *)config options:(NSDictionary *)options { - if (options[BSGKeyMaxBreadcrumbs] && [options[BSGKeyMaxBreadcrumbs] isKindOfClass:[NSNumber class]]) { - NSNumber *num = options[BSGKeyMaxBreadcrumbs]; - config.maxBreadcrumbs = [num unsignedIntValue]; - } -} - + (void)loadSendThreads:(BugsnagConfiguration *)config options:(NSDictionary *)options { if (options[BSGKeySendThreads] && [options[BSGKeySendThreads] isKindOfClass:[NSString class]]) { NSString *sendThreads = [options[BSGKeySendThreads] lowercaseString]; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BugsnagConfiguration+Private.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BugsnagConfiguration+Private.h index 9e20d5c890..ad2a2585db 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BugsnagConfiguration+Private.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BugsnagConfiguration+Private.h @@ -14,13 +14,14 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark Initializers -/// Initializes the configuration with values previously stored in metadata. -- (instancetype)initWithMetadata:(NSDictionary *)JSONObject NS_DESIGNATED_INITIALIZER; +- (instancetype)initWithDictionaryRepresentation:(NSDictionary *)JSONObject NS_DESIGNATED_INITIALIZER; #pragma mark Properties -/// Meta-information about the state of Bugsnag -@property (retain, nullable) BugsnagMetadata *config; +/// The user defaults database to use for persistence of user information. +@property (class, nonatomic) NSUserDefaults *userDefaults; + +@property (readonly) NSDictionary *dictionaryRepresentation; @property (readonly) NSDictionary *errorApiHeaders; @@ -49,6 +50,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)deletePersistedUserData; +- (BOOL)shouldDiscardErrorClass:(NSString *)errorClass; + - (BOOL)shouldRecordBreadcrumbType:(BSGBreadcrumbType)breadcrumbType; /// Throws an NSInvalidArgumentException if the API key is empty or missing. diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BugsnagConfiguration.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BugsnagConfiguration.m index 1d9c043687..001e893a76 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BugsnagConfiguration.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Configuration/BugsnagConfiguration.m @@ -51,6 +51,12 @@ @implementation BugsnagConfiguration +static NSUserDefaults *userDefaults; + ++ (void)initialize { + userDefaults = NSUserDefaults.standardUserDefaults; +} + + (instancetype _Nonnull)loadConfig { NSDictionary *options = [[NSBundle mainBundle] infoDictionary][@"bugsnag"]; return [BSGConfigurationBuilder configurationFromOptions:options]; @@ -77,12 +83,14 @@ - (nonnull id)copyWithZone:(nullable NSZone *)zone { [copy setAutoDetectErrors:self.autoDetectErrors]; [copy setAutoTrackSessions:self.autoTrackSessions]; [copy setBundleVersion:self.bundleVersion]; - [copy setConfig:[[BugsnagMetadata alloc] initWithDictionary:[[self.config toDictionary] mutableCopy]]]; [copy setContext:self.context]; [copy setEnabledBreadcrumbTypes:self.enabledBreadcrumbTypes]; [copy setEnabledErrorTypes:self.enabledErrorTypes]; [copy setEnabledReleaseStages:self.enabledReleaseStages]; + copy.discardClasses = self.discardClasses; [copy setRedactedKeys:self.redactedKeys]; + [copy setMaxPersistedEvents:self.maxPersistedEvents]; + [copy setMaxPersistedSessions:self.maxPersistedSessions]; [copy setMaxBreadcrumbs:self.maxBreadcrumbs]; copy->_metadata = [[BugsnagMetadata alloc] initWithDictionary:[[self.metadata toDictionary] mutableCopy]]; [copy setEndpoints:self.endpoints]; @@ -90,7 +98,7 @@ - (nonnull id)copyWithZone:(nullable NSZone *)zone { [copy setPersistUser:self.persistUser]; [copy setPlugins:[self.plugins copy]]; [copy setReleaseStage:self.releaseStage]; - [copy setSession:[self.session copy]]; + copy.session = self.session; // NSURLSession does not declare conformance to NSCopying [copy setSendThreads:self.sendThreads]; [copy setUser:self.user.id withEmail:self.user.email @@ -124,6 +132,14 @@ + (BOOL)isValidApiKey:(NSString *)apiKey { return isHex && [apiKey length] == BSGApiKeyLength; } ++ (void)setUserDefaults:(NSUserDefaults *)newValue { + userDefaults = newValue; +} + ++ (NSUserDefaults *)userDefaults { + return userDefaults; +} + // ----------------------------------------------------------------------------- // MARK: - Initializers // ----------------------------------------------------------------------------- @@ -147,7 +163,6 @@ - (instancetype)initWithApiKey:(NSString *)apiKey { [self setApiKey:apiKey]; } _metadata = [[BugsnagMetadata alloc] init]; - _config = [[BugsnagMetadata alloc] init]; _endpoints = [BugsnagEndpointConfiguration new]; _sessionURL = [NSURL URLWithString:@"https://sessions.bugsnag.com"]; _autoDetectErrors = YES; @@ -159,6 +174,8 @@ - (instancetype)initWithApiKey:(NSString *)apiKey { _enabledReleaseStages = nil; _redactedKeys = [NSSet setWithArray:@[@"password"]]; _enabledBreadcrumbTypes = BSGEnabledBreadcrumbTypeAll; + _maxPersistedEvents = 12; + _maxPersistedSessions = 32; _maxBreadcrumbs = 25; _autoTrackSessions = YES; _sendThreads = BSGThreadSendPolicyAlways; @@ -205,15 +222,16 @@ - (instancetype)initWithApiKey:(NSString *)apiKey { return self; } -- (instancetype)initWithMetadata:(NSDictionary *)metadata { +- (instancetype)initWithDictionaryRepresentation:(NSDictionary *)dictionaryRepresentation { if (!(self = [super init])) { return nil; } - _appVersion = metadata[BSGKeyAppVersion]; - _context = metadata[BSGKeyContext]; - _bundleVersion = metadata[BSGKeyBundleVersion]; - _enabledReleaseStages = metadata[BSGKeyEnabledReleaseStages]; - _releaseStage = metadata[BSGKeyReleaseStage]; + _appType = dictionaryRepresentation[BSGKeyAppType]; + _appVersion = dictionaryRepresentation[BSGKeyAppVersion]; + _bundleVersion = dictionaryRepresentation[BSGKeyBundleVersion]; + _context = dictionaryRepresentation[BSGKeyContext]; + _enabledReleaseStages = dictionaryRepresentation[BSGKeyEnabledReleaseStages]; + _releaseStage = dictionaryRepresentation[BSGKeyReleaseStage]; return self; } @@ -221,6 +239,17 @@ - (instancetype)initWithMetadata:(NSDictionary *)metadata { // MARK: - Instance Methods // ----------------------------------------------------------------------------- +- (NSDictionary *)dictionaryRepresentation { + NSMutableDictionary *dictionaryRepresentation = [NSMutableDictionary dictionary]; + dictionaryRepresentation[BSGKeyAppType] = self.appType; + dictionaryRepresentation[BSGKeyAppVersion] = self.appVersion; + dictionaryRepresentation[BSGKeyBundleVersion] = self.bundleVersion; + dictionaryRepresentation[BSGKeyContext] = self.context; + dictionaryRepresentation[BSGKeyEnabledReleaseStages] = self.enabledReleaseStages.allObjects; + dictionaryRepresentation[BSGKeyReleaseStage] = self.releaseStage; + return dictionaryRepresentation; +} + /** * Whether reports should be sent, based on release stage options * @@ -350,7 +379,6 @@ - (void)setPersistUser:(BOOL)persistUser { */ - (BugsnagUser *)getPersistedUserData { @synchronized(self) { - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; NSString *email = [userDefaults objectForKey:kBugsnagUserEmailAddress]; NSString *name = [userDefaults objectForKey:kBugsnagUserName]; NSString *userId = [userDefaults objectForKey:kBugsnagUserUserId]; @@ -370,8 +398,6 @@ - (BugsnagUser *)getPersistedUserData { - (void)persistUserData { @synchronized(self) { if (_user) { - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; - // Email if (_user.email) { [userDefaults setObject:_user.email forKey:kBugsnagUserEmailAddress]; @@ -404,7 +430,6 @@ - (void)persistUserData { */ -(void)deletePersistedUserData { @synchronized(self) { - NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults]; [userDefaults removeObjectForKey:kBugsnagUserEmailAddress]; [userDefaults removeObjectForKey:kBugsnagUserName]; [userDefaults removeObjectForKey:kBugsnagUserUserId]; @@ -415,6 +440,46 @@ -(void)deletePersistedUserData { // MARK: - Properties: Getters and Setters // ----------------------------------------------------------------------------- +@synthesize maxPersistedEvents = _maxPersistedEvents; + +- (NSUInteger)maxPersistedEvents { + @synchronized (self) { + return _maxPersistedEvents; + } +} + +- (void)setMaxPersistedEvents:(NSUInteger)maxPersistedEvents { + @synchronized (self) { + if (maxPersistedEvents >= 1 && maxPersistedEvents <= 100) { + _maxPersistedEvents = maxPersistedEvents; + } else { + bsg_log_err(@"Invalid configuration value detected. Option maxPersistedEvents " + "should be an integer between 1-100. Supplied value is %lu", + (unsigned long) maxPersistedEvents); + } + } +} + +@synthesize maxPersistedSessions = _maxPersistedSessions; + +- (NSUInteger)maxPersistedSessions { + @synchronized (self) { + return _maxPersistedSessions; + } +} + +- (void)setMaxPersistedSessions:(NSUInteger)maxPersistedSessions { + @synchronized (self) { + if (maxPersistedSessions >= 1 && maxPersistedSessions <= 100) { + _maxPersistedSessions = maxPersistedSessions; + } else { + bsg_log_err(@"Invalid configuration value detected. Option maxPersistedSessions " + "should be an integer between 1-100. Supplied value is %lu", + (unsigned long) maxPersistedSessions); + } + } +} + @synthesize maxBreadcrumbs = _maxBreadcrumbs; - (NSUInteger)maxBreadcrumbs { @@ -435,6 +500,21 @@ - (void)setMaxBreadcrumbs:(NSUInteger)maxBreadcrumbs { } } +- (BOOL)shouldDiscardErrorClass:(NSString *)errorClass { + for (id obj in self.discardClasses) { + if ([obj isKindOfClass:[NSString class]]) { + if ([obj isEqualToString:errorClass]) { + return YES; + } + } else if ([obj isKindOfClass:[NSRegularExpression class]]) { + if ([obj firstMatchInString:errorClass options:0 range:NSMakeRange(0, errorClass.length)]) { + return YES; + } + } + } + return NO; +} + /** * Specific types of breadcrumb should be recorded if either enabledBreadcrumbTypes * is None, or contains the type. @@ -469,49 +549,6 @@ - (BOOL)shouldRecordBreadcrumbType:(BSGBreadcrumbType)type { return NO; } -// MARK: - - -@synthesize releaseStage = _releaseStage; - -- (NSString *)releaseStage { - @synchronized (self) { - return _releaseStage; - } -} - -- (void)setReleaseStage:(NSString *)newReleaseStage { - @synchronized (self) { - NSString *key = NSStringFromSelector(@selector(releaseStage)); - [self willChangeValueForKey:key]; - _releaseStage = newReleaseStage; - [self didChangeValueForKey:key]; - [self.config addMetadata:newReleaseStage - withKey:BSGKeyReleaseStage - toSection:BSGKeyConfig]; - } -} - -// MARK: - - -@synthesize enabledReleaseStages = _enabledReleaseStages; - -- (NSSet *)enabledReleaseStages { - @synchronized (self) { - return _enabledReleaseStages; - } -} - -- (void)setEnabledReleaseStages:(NSSet *)newReleaseStages -{ - @synchronized (self) { - NSSet *releaseStagesCopy = [newReleaseStages copy]; - _enabledReleaseStages = releaseStagesCopy; - [self.config addMetadata:[releaseStagesCopy allObjects] - withKey:BSGKeyEnabledReleaseStages - toSection:BSGKeyConfig]; - } -} - // MARK: - enabledBreadcrumbTypes @synthesize enabledBreadcrumbTypes = _enabledBreadcrumbTypes; @@ -530,63 +567,6 @@ - (void)setEnabledBreadcrumbTypes:(BSGEnabledBreadcrumbType)enabledBreadcrumbTyp // MARK: - -@synthesize context = _context; - -- (NSString *)context { - @synchronized (self) { - return _context; - } -} - -- (void)setContext:(NSString *)newContext { - @synchronized (self) { - _context = newContext; - [self.config addMetadata:newContext - withKey:BSGKeyContext - toSection:BSGKeyConfig]; - } -} - -// MARK: - - -@synthesize appVersion = _appVersion; - -- (NSString *)appVersion { - @synchronized (self) { - return _appVersion; - } -} - -- (void)setAppVersion:(NSString *)newVersion { - @synchronized (self) { - _appVersion = newVersion; - [self.config addMetadata:newVersion - withKey:BSGKeyAppVersion - toSection:BSGKeyConfig]; - } -} - -// MARK: - - -@synthesize bundleVersion = _bundleVersion; - -- (NSString *)bundleVersion { - @synchronized (self) { - return _bundleVersion; - } -} - -- (void)setBundleVersion:(NSString *)newVersion { - @synchronized (self) { - _bundleVersion = newVersion; - [self.config addMetadata:newVersion - withKey:BSGKeyBundleVersion - toSection:BSGKeyConfig]; - } -} - -// MARK: - - - (void)validate { if (self.apiKey.length == 0) { @throw [NSException exceptionWithName:NSInvalidArgumentException reason: @@ -594,7 +574,7 @@ - (void)validate { } if (![BugsnagConfiguration isValidApiKey:self.apiKey]) { - bsg_log_warn(@"Invalid Bugsnag apiKey: expected a 32-character hexademical string, got \"%@\"", self.apiKey); + bsg_log_warn(@"Invalid apiKey: expected a 32-character hexademical string, got \"%@\"", self.apiKey); } } diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagErrorReportApiClient.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagErrorReportApiClient.m index b9bb89a900..859e6b00a8 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagErrorReportApiClient.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagErrorReportApiClient.m @@ -7,11 +7,14 @@ // #import "BugsnagErrorReportApiClient.h" + +#import "BSG_KSCrash.h" #import "Bugsnag.h" -#import "BugsnagLogger.h" #import "BugsnagClient.h" #import "BugsnagErrorReportSink.h" #import "BugsnagKeys.h" +#import "BugsnagLogger.h" + @interface BSGDeliveryOperation : NSOperation @end diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagSessionTrackingApiClient.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagSessionTrackingApiClient.h index 08dc7dde57..abe1b71ba7 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagSessionTrackingApiClient.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagSessionTrackingApiClient.h @@ -7,11 +7,12 @@ #import "BugsnagApiClient.h" @class BugsnagConfiguration; +@class BugsnagNotifier; @class BugsnagSessionFileStore; @interface BugsnagSessionTrackingApiClient : BugsnagApiClient -- (instancetype)initWithConfig:(BugsnagConfiguration *)configuration queueName:(NSString *)queueName; +- (instancetype)initWithConfig:(BugsnagConfiguration *)configuration queueName:(NSString *)queueName notifier:(BugsnagNotifier *)notifier; /** * Asynchronously delivers sessions written to the store @@ -22,4 +23,6 @@ @property (copy) NSString *codeBundleId; +@property BugsnagNotifier *notifier; + @end diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagSessionTrackingApiClient.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagSessionTrackingApiClient.m index d8f4467622..67f783b60c 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagSessionTrackingApiClient.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Delivery/BugsnagSessionTrackingApiClient.m @@ -5,7 +5,6 @@ #import "BugsnagSessionTrackingApiClient.h" -#import "Bugsnag+Private.h" #import "BugsnagConfiguration+Private.h" #import "BugsnagSessionTrackingPayload.h" #import "BugsnagSessionFileStore.h" @@ -22,10 +21,11 @@ @interface BugsnagSessionTrackingApiClient () @implementation BugsnagSessionTrackingApiClient -- (instancetype)initWithConfig:(BugsnagConfiguration *)configuration queueName:(NSString *)queueName { +- (instancetype)initWithConfig:(BugsnagConfiguration *)configuration queueName:(NSString *)queueName notifier:(BugsnagNotifier *)notifier { if ((self = [super initWithSession:configuration.session queueName:queueName])) { _activeIds = [NSMutableSet new]; _config = configuration; + _notifier = notifier; } return self; } @@ -61,8 +61,9 @@ - (void)deliverSessionsInStore:(BugsnagSessionFileStore *)store { [self.sendQueue addOperationWithBlock:^{ BugsnagSessionTrackingPayload *payload = [[BugsnagSessionTrackingPayload alloc] initWithSessions:@[session] - config:[Bugsnag configuration] - codeBundleId:self.codeBundleId]; + config:self.config + codeBundleId:self.codeBundleId + notifier:self.notifier]; NSMutableDictionary *data = [payload toJson]; NSDictionary *HTTPHeaders = @{ BugsnagHTTPHeaderNameApiKey: apiKey ?: @"", @@ -73,14 +74,14 @@ - (void)deliverSessionsInStore:(BugsnagSessionFileStore *)store { completionHandler:^(BugsnagApiClientDeliveryStatus status, NSError *error) { switch (status) { case BugsnagApiClientDeliveryStatusDelivered: - bsg_log_info(@"Sent session %@ to Bugsnag", session.id); + bsg_log_info(@"Sent session %@", session.id); [store deleteFileWithId:fileId]; break; case BugsnagApiClientDeliveryStatusFailed: - bsg_log_warn(@"Failed to send sessions to Bugsnag: %@", error); + bsg_log_warn(@"Failed to send sessions: %@", error); break; case BugsnagApiClientDeliveryStatusUndeliverable: - bsg_log_warn(@"Failed to send sessions to Bugsnag: %@", error); + bsg_log_warn(@"Failed to send sessions: %@", error); [store deleteFileWithId:fileId]; break; } diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BSGCachesDirectory.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BSGCachesDirectory.m index b0a9d0ea23..b195410568 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BSGCachesDirectory.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BSGCachesDirectory.m @@ -7,7 +7,8 @@ // #import "BSGCachesDirectory.h" -#import "BSG_KSLogger.h" + +#import "BugsnagLogger.h" @implementation BSGCachesDirectory @@ -21,12 +22,12 @@ + (NSString *)cachesDirectory { dispatch_once(&onceToken, ^{ NSArray *dirs = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); if ([dirs count] == 0) { - BSG_KSLOG_ERROR(@"Could not locate cache directory path."); + bsg_log_err(@"Could not locate cache directory path."); return; } if ([dirs[0] length] == 0) { - BSG_KSLOG_ERROR(@"Could not locate cache directory path."); + bsg_log_err(@"Could not locate cache directory path."); return; } cachesPath = dirs[0]; @@ -42,7 +43,7 @@ + (NSString *)getSubdirPath:(NSString *)relativePath { NSFileManager *fileManager = [NSFileManager defaultManager]; NSError *error = nil; if(![fileManager createDirectoryAtPath:subdirPath withIntermediateDirectories:YES attributes:nil error:&error]) { - BSG_KSLOG_ERROR(@"Could not create caches subdir %@: %@", subdirPath, error); + bsg_log_err(@"Could not create caches subdir %@: %@", subdirPath, error); // Make the best of it, just return the top-level caches dir. return cachesDir; } diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagKeys.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagKeys.h index aeba03ee38..37c8c1cb38 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagKeys.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagKeys.h @@ -42,8 +42,8 @@ extern NSString *const BSGKeyExceptionName; extern NSString *const BSGKeyExceptions; extern NSString *const BSGKeyExecutableName; extern NSString *const BSGKeyExtraRuntimeInfo; -extern NSString *const BSGKeyFrameAddrFormat; extern NSString *const BSGKeyFrameAddress; +extern NSString *const BSGKeyFrameAddrFormat; extern NSString *const BSGKeyGroupingHash; extern NSString *const BSGKeyHwMachine; extern NSString *const BSGKeyHwModel; @@ -63,6 +63,8 @@ extern NSString *const BSGKeyMachoLoadAddr; extern NSString *const BSGKeyMachoUUID; extern NSString *const BSGKeyMachoVMAddress; extern NSString *const BSGKeyMaxBreadcrumbs; +extern NSString *const BSGKeyMaxPersistedEvents; +extern NSString *const BSGKeyMaxPersistedSessions; extern NSString *const BSGKeyMessage; extern NSString *const BSGKeyMetadata; extern NSString *const BSGKeyMethod; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagKeys.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagKeys.m index 300a94fb30..62d22abb0c 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagKeys.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagKeys.m @@ -38,8 +38,8 @@ NSString *const BSGKeyExceptions = @"exceptions"; NSString *const BSGKeyExecutableName = @"CFBundleExecutable"; NSString *const BSGKeyExtraRuntimeInfo = @"extraRuntimeInfo"; -NSString *const BSGKeyFrameAddrFormat = @"0x%lx"; NSString *const BSGKeyFrameAddress = @"frameAddress"; +NSString *const BSGKeyFrameAddrFormat = @"0x%lx"; NSString *const BSGKeyGroupingHash = @"groupingHash"; NSString *const BSGKeyHwMachine = @"hw.machine"; NSString *const BSGKeyHwModel = @"hw.model"; @@ -59,6 +59,8 @@ NSString *const BSGKeyMachoUUID = @"machoUUID"; NSString *const BSGKeyMachoVMAddress = @"machoVMAddress"; NSString *const BSGKeyMaxBreadcrumbs = @"maxBreadcrumbs"; +NSString *const BSGKeyMaxPersistedEvents = @"maxPersistedEvents"; +NSString *const BSGKeyMaxPersistedSessions = @"maxPersistedSessions"; NSString *const BSGKeyMessage = @"message"; NSString *const BSGKeyMetadata = @"metaData"; NSString *const BSGKeyMethod = @"method"; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagLogger.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagLogger.h index f4bb4e8331..c1ad6212fe 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagLogger.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Helpers/BugsnagLogger.h @@ -24,9 +24,6 @@ * That file includes this one. No further configuration is required. */ -#ifndef BugsnagLogger_h -#define BugsnagLogger_h - #define BSG_LOGLEVEL_NONE 0 #define BSG_LOGLEVEL_ERR 10 #define BSG_LOGLEVEL_WARN 20 @@ -38,28 +35,32 @@ #define BSG_LOG_LEVEL BSG_LOGLEVEL_INFO #endif +#ifdef __OBJC__ + +#import + #if BSG_LOG_LEVEL >= BSG_LOGLEVEL_ERR -#define bsg_log_err NSLog +#define bsg_log_err(...) NSLog(@"[Bugsnag] [ERROR] " __VA_ARGS__) #else #define bsg_log_err(format, ...) #endif #if BSG_LOG_LEVEL >= BSG_LOGLEVEL_WARN -#define bsg_log_warn NSLog +#define bsg_log_warn(...) NSLog(@"[Bugsnag] [WARN] " __VA_ARGS__) #else #define bsg_log_warn(format, ...) #endif #if BSG_LOG_LEVEL >= BSG_LOGLEVEL_INFO -#define bsg_log_info NSLog +#define bsg_log_info(...) NSLog(@"[Bugsnag] [INFO] " __VA_ARGS__) #else #define bsg_log_info(format, ...) #endif #if BSG_LOG_LEVEL >= BSG_LOGLEVEL_DEBUG -#define bsg_log_debug NSLog +#define bsg_log_debug(...) NSLog(@"[Bugsnag] [DEBUG] " __VA_ARGS__) #else #define bsg_log_debug(format, ...) #endif -#endif /* BugsnagLogger_h */ +#endif diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.m index a001905b54..1c47cf9900 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrash.m @@ -283,7 +283,7 @@ - (void)sendAllReports { NSDictionary *reports = [self allReportsByFilename]; - BSG_KSLOG_INFO(@"Sending %d crash reports", [reports count]); + BSG_KSLOG_INFO(@"Sending %lu crash reports", (unsigned long)reports.count); [self sendReports:reports withBlock:^(NSString *filename, BOOL completed, diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c index 20207a14a4..59d728d192 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReport.c @@ -965,6 +965,27 @@ void bsg_kscrw_i_writeNotableAddresses( writer->endContainer(writer); } +/** Write the message from the `__crash_info` Mach section into the report. + * + * @param writer The writer. + * + * @param key The object key. + * + * @param address The address of the first frame in the backtrace. + */ +void bsg_kscrw_i_writeCrashInfoMessage(const BSG_KSCrashReportWriter *const writer, + const char *key, uintptr_t address) { + BSG_Mach_Header_Info *image = bsg_mach_headers_image_at_address(address); + if (!image) { + BSG_KSLOG_ERROR("Could not locate mach header info"); + return; + } + const char *message = bsg_mach_headers_get_crash_info_message(image); + if (message) { + writer->addStringElement(writer, key, message); + } +} + /** Write information about a thread to the report. * * @param writer The writer. @@ -1021,6 +1042,10 @@ void bsg_kscrw_i_writeThread(const BSG_KSCrashReportWriter *const writer, writer, BSG_KSCrashField_NotableAddresses, machineContext); } } + if (isCrashedThread && backtrace && backtraceLength) { + bsg_kscrw_i_writeCrashInfoMessage(writer, BSG_KSCrashField_CrashInfoMessage, + backtrace[0]); + } } writer->endContainer(writer); } diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReportFields.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReportFields.h index 475c7e0053..44aa19d5fa 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReportFields.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/BSG_KSCrashReportFields.h @@ -95,6 +95,7 @@ #define BSG_KSCrashField_Backtrace "backtrace" #define BSG_KSCrashField_Basic "basic" #define BSG_KSCrashField_Crashed "crashed" +#define BSG_KSCrashField_CrashInfoMessage "crash_info_message" #define BSG_KSCrashField_CurrentThread "current_thread" #define BSG_KSCrashField_DispatchQueue "dispatch_queue" #define BSG_KSCrashField_NotableAddresses "notable_addresses" diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSLogger.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSLogger.h index 7676817d3f..4700260602 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSLogger.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSLogger.h @@ -356,6 +356,24 @@ bool bsg_kslog_setLogFilename(const char *filename, bool overwrite); #undef BSG_KSLOG_BAK_TRACE #endif +#ifdef __OBJC__ + +#pragma mark - Redirect BSG_KSLOG_* to bsg_log_* so that logging output has a unified format. + +#undef BSG_KSLOG_ERROR +#undef BSG_KSLOG_WARN +#undef BSG_KSLOG_INFO +#undef BSG_KSLOG_DEBUG +#undef BSG_KSLOG_TRACE + +#define BSG_KSLOG_ERROR bsg_log_err +#define BSG_KSLOG_WARN bsg_log_warn +#define BSG_KSLOG_INFO bsg_log_info +#define BSG_KSLOG_DEBUG bsg_log_debug +#define BSG_KSLOG_TRACE bsg_log_debug + +#endif // __OBJC__ + #ifdef __cplusplus } #endif diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachHeaders.c b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachHeaders.c new file mode 100644 index 0000000000..4b30496090 --- /dev/null +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachHeaders.c @@ -0,0 +1,340 @@ +// +// BSG_KSMachHeaders.c +// Bugsnag +// +// Created by Robin Macharg on 04/05/2020. +// Copyright © 2020 Bugsnag. All rights reserved. +// + +#include "BSG_KSMachHeaders.h" + +#include "BSG_KSDynamicLinker.h" +#include "BSG_KSMach.h" + +#include +#include +#include +#include + +// Copied from https://github.com/apple/swift/blob/swift-5.0-RELEASE/include/swift/Runtime/Debug.h#L28-L40 + +#define CRASHREPORTER_ANNOTATIONS_VERSION 5 +#define CRASHREPORTER_ANNOTATIONS_SECTION "__crash_info" + +struct crashreporter_annotations_t { + uint64_t version; // unsigned long + uint64_t message; // char * + uint64_t signature_string; // char * + uint64_t backtrace; // char * + uint64_t message2; // char * + uint64_t thread; // uint64_t + uint64_t dialog_mode; // unsigned int + uint64_t abort_cause; // unsigned int +}; + +// MARK: - Mach Header Linked List + +static BSG_Mach_Header_Info *bsg_g_mach_headers_images_head; +static BSG_Mach_Header_Info *bsg_g_mach_headers_images_tail; +static dispatch_queue_t bsg_g_serial_queue; + +BSG_Mach_Header_Info *bsg_mach_headers_get_images() { + return bsg_g_mach_headers_images_head; +} + +void bsg_mach_headers_initialize() { + + // Clear any existing headers to reset the head/tail pointers + for (BSG_Mach_Header_Info *img = bsg_g_mach_headers_images_head; img != NULL; ) { + BSG_Mach_Header_Info *imgToDelete = img; + img = img->next; + free(imgToDelete); + } + + bsg_g_mach_headers_images_head = NULL; + bsg_g_mach_headers_images_tail = NULL; + bsg_g_serial_queue = dispatch_queue_create("com.bugsnag.mach-headers", DISPATCH_QUEUE_SERIAL); +} + +void bsg_mach_headers_register_for_changes() { + + // Register for binary images being loaded and unloaded. dyld calls the add function once + // for each library that has already been loaded and then keeps this cache up-to-date + // with future changes + _dyld_register_func_for_add_image(&bsg_mach_headers_add_image); + _dyld_register_func_for_remove_image(&bsg_mach_headers_remove_image); + +} + +/** + * Populate a Mach binary image info structure + * + * @param header The Mach binary image header + * + * @param info Encapsulated Binary Image info + * + * @returns a boolean indicating success + */ +bool bsg_mach_headers_populate_info(const struct mach_header *header, intptr_t slide, BSG_Mach_Header_Info *info) { + + // Early exit conditions; this is not a valid/useful binary image + // 1. We can't find a sensible Mach command + uintptr_t cmdPtr = bsg_mach_headers_first_cmd_after_header(header); + if (cmdPtr == 0) { + return false; + } + + // 2. The image doesn't have a name. Note: running with a debugger attached causes this condition to match. + Dl_info DlInfo = (const Dl_info) { 0 }; + dladdr(header, &DlInfo); + const char *imageName = DlInfo.dli_fname; + if (!imageName) { + return false; + } + + // Look for the TEXT segment to get the image size. + // Also look for a UUID command. + uint64_t imageSize = 0; + uint64_t imageVmAddr = 0; + uint8_t *uuid = NULL; + + for (uint32_t iCmd = 0; iCmd < header->ncmds; iCmd++) { + struct load_command *loadCmd = (struct load_command *)cmdPtr; + switch (loadCmd->cmd) { + case LC_SEGMENT: { + struct segment_command *segCmd = (struct segment_command *)cmdPtr; + if (strcmp(segCmd->segname, SEG_TEXT) == 0) { + imageSize = segCmd->vmsize; + imageVmAddr = segCmd->vmaddr; + } + break; + } + case LC_SEGMENT_64: { + struct segment_command_64 *segCmd = + (struct segment_command_64 *)cmdPtr; + if (strcmp(segCmd->segname, SEG_TEXT) == 0) { + imageSize = segCmd->vmsize; + imageVmAddr = segCmd->vmaddr; + } + break; + } + case LC_UUID: { + struct uuid_command *uuidCmd = (struct uuid_command *)cmdPtr; + uuid = uuidCmd->uuid; + break; + } + } + cmdPtr += loadCmd->cmdsize; + } + + // Save these values + info->header = header; + info->imageSize = imageSize; + info->imageVmAddr = imageVmAddr; + info->uuid = uuid; + info->name = imageName; + info->slide = slide; + info->unloaded = FALSE; + info->next = NULL; + + return true; +} + +void bsg_mach_headers_add_image(const struct mach_header *header, intptr_t slide) { + BSG_Mach_Header_Info *newImage = malloc(sizeof(BSG_Mach_Header_Info)); + if (newImage != NULL) { + if (bsg_mach_headers_populate_info(header, slide, newImage)) { + dispatch_sync(bsg_g_serial_queue, ^{ + if (bsg_g_mach_headers_images_head == NULL) { + bsg_g_mach_headers_images_head = newImage; + } else { + bsg_g_mach_headers_images_tail->next = newImage; + } + bsg_g_mach_headers_images_tail = newImage; + }); + } + } +} + +/** + * To avoid a destructive operation that could lead thread safety problems, we maintain the + * image record, but mark it as unloaded + */ +void bsg_mach_headers_remove_image(const struct mach_header *header, intptr_t slide) { + BSG_Mach_Header_Info existingImage = { 0 }; + if (bsg_mach_headers_populate_info(header, slide, &existingImage)) { + for (BSG_Mach_Header_Info *img = bsg_g_mach_headers_images_head; img != NULL; img = img->next) { + if (img->imageVmAddr == existingImage.imageVmAddr) { + img->unloaded = true; + } + } + } +} + +BSG_Mach_Header_Info *bsg_mach_headers_image_named(const char *const imageName, bool exactMatch) { + + if (imageName != NULL) { + + for (BSG_Mach_Header_Info *img = bsg_g_mach_headers_images_head; img != NULL; img = img->next) { + if (img->name == NULL) { + continue; // name is null if the index is out of range per dyld(3) + } else if (img->unloaded == true) { + continue; // ignore unloaded libraries + } else if (exactMatch) { + if (strcmp(img->name, imageName) == 0) { + return img; + } + } else { + if (strstr(img->name, imageName) != NULL) { + return img; + } + } + } + } + + return NULL; +} + +BSG_Mach_Header_Info *bsg_mach_headers_image_at_address(const uintptr_t address) { + + for (BSG_Mach_Header_Info *img = bsg_g_mach_headers_images_head; img != NULL; img = img->next) { + if (img->unloaded == true) { + continue; + } + // Look for a segment command with this address within its range. + uintptr_t cmdPtr = bsg_mach_headers_first_cmd_after_header(img->header); + if (cmdPtr == 0) { + continue; + } + uintptr_t addressWSlide = address - img->slide; + for (uint32_t iCmd = 0; iCmd < img->header->ncmds; iCmd++) { + const struct load_command *loadCmd = + (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_SEGMENT) { + const struct segment_command *segCmd = + (struct segment_command *)cmdPtr; + if (addressWSlide >= segCmd->vmaddr && + addressWSlide < segCmd->vmaddr + segCmd->vmsize) { + return img; + } + } else if (loadCmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64 *segCmd = + (struct segment_command_64 *)cmdPtr; + if (addressWSlide >= segCmd->vmaddr && + addressWSlide < segCmd->vmaddr + segCmd->vmsize) { + return img; + } + } + cmdPtr += loadCmd->cmdsize; + } + } + + return NULL; +} + +uintptr_t bsg_mach_headers_first_cmd_after_header(const struct mach_header *const header) { + if (header == NULL) { + return 0; + } + switch (header->magic) { + case MH_MAGIC: + case MH_CIGAM: + return (uintptr_t)(header + 1); + case MH_MAGIC_64: + case MH_CIGAM_64: + return (uintptr_t)(((struct mach_header_64 *)header) + 1); + default: + // Header is corrupt + return 0; + } +} + +uintptr_t bsg_mach_headers_image_at_base_of_image_index(const struct mach_header *const header) { + // Look for a segment command and return the file image address. + uintptr_t cmdPtr = bsg_mach_headers_first_cmd_after_header(header); + if (cmdPtr == 0) { + return 0; + } + for (uint32_t i = 0; i < header->ncmds; i++) { + const struct load_command *loadCmd = (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_SEGMENT) { + const struct segment_command *segmentCmd = + (struct segment_command *)cmdPtr; + if (strcmp(segmentCmd->segname, SEG_LINKEDIT) == 0) { + return segmentCmd->vmaddr - segmentCmd->fileoff; + } + } else if (loadCmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64 *segmentCmd = + (struct segment_command_64 *)cmdPtr; + if (strcmp(segmentCmd->segname, SEG_LINKEDIT) == 0) { + return (uintptr_t)(segmentCmd->vmaddr - segmentCmd->fileoff); + } + } + cmdPtr += loadCmd->cmdsize; + } + + return 0; +} +static uintptr_t bsg_mach_header_info_get_section_addr_named(const BSG_Mach_Header_Info *header, const char *name) { + uintptr_t cmdPtr = bsg_mach_headers_first_cmd_after_header(header->header); + if (!cmdPtr) { + return 0; + } + for (uint32_t i = 0; i < header->header->ncmds; i++) { + const struct load_command *loadCmd = (struct load_command *)cmdPtr; + if (loadCmd->cmd == LC_SEGMENT) { + const struct segment_command *segment = (void *)cmdPtr; + char *sectionPtr = (void *)(cmdPtr + sizeof(*segment)); + for (uint32_t i = 0; i < segment->nsects; i++) { + struct section *section = (void *)sectionPtr; + if (strcmp(name, section->sectname) == 0) { + return section->addr + header->slide; + } + sectionPtr += sizeof(*section); + } + } else if (loadCmd->cmd == LC_SEGMENT_64) { + const struct segment_command_64 *segment = (void *)cmdPtr; + char *sectionPtr = (void *)(cmdPtr + sizeof(*segment)); + for (uint32_t i = 0; i < segment->nsects; i++) { + struct section_64 *section = (void *)sectionPtr; + if (strcmp(name, section->sectname) == 0) { + return (uintptr_t)section->addr + header->slide; + } + sectionPtr += sizeof(*section); + } + } + cmdPtr += loadCmd->cmdsize; + } + return 0; +} + +const char *bsg_mach_headers_get_crash_info_message(const BSG_Mach_Header_Info *header) { + struct crashreporter_annotations_t info; + uintptr_t sectionAddress = bsg_mach_header_info_get_section_addr_named(header, CRASHREPORTER_ANNOTATIONS_SECTION); + if (!sectionAddress) { + return NULL; + } + if (bsg_ksmachcopyMem((void *)sectionAddress, &info, sizeof(info)) != KERN_SUCCESS) { + return NULL; + } + // Version 4 was in use until iOS 9 / Swift 2.0 when the version was bumped to 5. + if (info.version > CRASHREPORTER_ANNOTATIONS_VERSION) { + return NULL; + } + if (!info.message) { + return NULL; + } + // Probe the string to ensure it's safe to read. + for (uintptr_t i = 0; i < 500; i++) { + char c; + if (bsg_ksmachcopyMem((void *)(info.message + i), &c, sizeof(c)) != KERN_SUCCESS) { + // String is not readable. + return NULL; + } + if (c == '\0') { + // Found end of string. + return (const char *)info.message; + } + } + return NULL; +} diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachHeaders.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachHeaders.h index 38f22f9853..376aad0e0f 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachHeaders.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSMachHeaders.h @@ -99,4 +99,11 @@ uintptr_t bsg_mach_headers_first_cmd_after_header(const struct mach_header *head */ uintptr_t bsg_mach_headers_image_at_base_of_image_index(const struct mach_header *header); +/** Get the __crash_info message of the specified image. + * + * @param header The header to get commands for. + * @return The __crash_info message, or NULL if no readable message could be found. + */ +const char *bsg_mach_headers_get_crash_info_message(const BSG_Mach_Header_Info *header); + #endif /* BSG_KSMachHeaders_h */ diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagError+Private.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagError+Private.h index 395fc45e75..99308add94 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagError+Private.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagError+Private.h @@ -23,6 +23,9 @@ NS_ASSUME_NONNULL_BEGIN + (BugsnagError *)errorFromJson:(NSDictionary *)json; +/// Parses the `__crash_info` message and updates the `errorClass` and `errorMessage` as appropriate. +- (void)updateWithCrashInfoMessage:(NSString *)crashInfoMessage; + - (NSDictionary *)toDictionary; @end diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagError.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagError.m index 960113a279..5771a3c1ce 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagError.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagError.m @@ -6,14 +6,16 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import "BugsnagError.h" +#import "BugsnagError+Private.h" +#import "BSG_KSCrashReportFields.h" +#import "BugsnagCollections.h" #import "BugsnagKeys.h" +#import "BugsnagLogger.h" #import "BugsnagStackframe+Private.h" #import "BugsnagStacktrace.h" -#import "BugsnagCollections.h" -#import "RegisterErrorData.h" -#import "BugsnagThread.h" +#import "BugsnagThread+Private.h" + NSString *_Nonnull BSGSerializeErrorType(BSGErrorType errorType) { switch (errorType) { @@ -87,12 +89,6 @@ - (instancetype)initWithEvent:(NSDictionary *)event errorReportingThread:(Bugsna _type = BSGErrorTypeCocoa; if (![[event valueForKeyPath:@"user.state.didOOM"] boolValue]) { - NSArray *threadDict = [event valueForKeyPath:@"crash.threads"]; - RegisterErrorData *data = [RegisterErrorData errorDataFromThreads:threadDict]; - if (data) { - _errorClass = data.errorClass; - _errorMessage = data.errorMessage; - } _stacktrace = thread.stacktrace; } } @@ -132,6 +128,36 @@ + (BugsnagError *)errorFromJson:(NSDictionary *)json { return error; } +- (void)updateWithCrashInfoMessage:(NSString *)crashInfoMessage { + @try { + // Messages that match this pattern should override the errorClass (and errorMessage if there is enough information.) + NSString *pattern = @"^(Assertion failed|Fatal error|Precondition failed): ((.+): )?file .+, line \\d+\n$"; + NSRegularExpression *regex = [[NSRegularExpression alloc] initWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:nil]; + NSArray *matches = [regex matchesInString:crashInfoMessage options:0 range:NSMakeRange(0, crashInfoMessage.length)]; + if (matches.count != 1 || matches[0].numberOfRanges != 4) { + if (!self.errorMessage.length) { + // It's better to fall back to the raw string than have an empty errorMessage. + self.errorMessage = crashInfoMessage; + } + return; + } + NSRange errorClassRange = [matches[0] rangeAtIndex:1]; + if (errorClassRange.location != NSNotFound) { + self.errorClass = [crashInfoMessage substringWithRange:errorClassRange]; + } + NSRange errorMessageRange = [matches[0] rangeAtIndex:3]; + if (errorMessageRange.location != NSNotFound) { + self.errorMessage = [crashInfoMessage substringWithRange:errorMessageRange]; + } + } @catch (NSException *exception) { + bsg_log_err(@"Exception thrown while parsing crash info message: %@", exception); + if (!self.errorMessage.length) { + // It's better to fall back to the raw string than have an empty errorMessage. + self.errorMessage = crashInfoMessage; + } + } +} + - (NSDictionary *)findErrorReportingThread:(NSDictionary *)event { NSArray *threads = [event valueForKeyPath:@"crash.threads"]; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagEvent+Private.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagEvent+Private.h index 745d6b1e1d..4104d4814f 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagEvent+Private.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagEvent+Private.h @@ -37,7 +37,7 @@ NS_ASSUME_NONNULL_BEGIN /// Property overrides. @property (readonly, copy) NSDictionary *overrides; -@property NSSet *redactedKeys; +@property NSSet *redactedKeys; /// The release stage of the application @property (readwrite, copy, nullable) NSString *releaseStage; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagEvent.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagEvent.m index 7c5d5984ed..8787468cdc 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagEvent.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagEvent.m @@ -8,6 +8,8 @@ #import "BugsnagPlatformConditional.h" +#import "BugsnagEvent+Private.h" + #if BSG_PLATFORM_IOS #import "BSGUIKit.h" #include @@ -27,7 +29,6 @@ #import "BugsnagConfiguration+Private.h" #import "BugsnagDeviceWithState+Private.h" #import "BugsnagError+Private.h" -#import "BugsnagEvent+Private.h" #import "BugsnagHandledState.h" #import "BugsnagKeys.h" #import "BugsnagMetadata+Private.h" @@ -36,7 +37,7 @@ #import "BugsnagStacktrace+Private.h" #import "BugsnagThread+Private.h" #import "BugsnagUser+Private.h" -#import "RegisterErrorData.h" + static NSString *const DEFAULT_EXCEPTION_TYPE = @"cocoa"; @@ -267,7 +268,7 @@ - (instancetype)initWithOOMData:(NSDictionary *)event { * @return a BugsnagEvent containing the parsed information */ - (instancetype)initWithKSCrashData:(NSDictionary *)event { - NSDictionary *error = [event valueForKeyPath:@"crash.error"]; + NSMutableDictionary *error = [[event valueForKeyPath:@"crash.error"] mutableCopy]; NSString *errorType = error[BSGKeyType]; // Always assume that a report coming from KSCrash is by default an unhandled error. @@ -333,6 +334,11 @@ - (instancetype)initWithKSCrashData:(NSDictionary *)event { NSArray *errors = @[[[BugsnagError alloc] initWithEvent:event errorReportingThread:errorReportingThread]]; + if (errorReportingThread.crashInfoMessage) { + [errors[0] updateWithCrashInfoMessage:errorReportingThread.crashInfoMessage]; + error[@"crashInfo"] = errorReportingThread.crashInfoMessage; + } + BugsnagHandledState *handledState; if (recordedState) { handledState = [[BugsnagHandledState alloc] initWithDictionary:recordedState]; @@ -356,11 +362,8 @@ - (instancetype)initWithKSCrashData:(NSDictionary *)event { NSString *deviceAppHash = [event valueForKeyPath:@"system.device_app_hash"]; BugsnagDeviceWithState *device = [BugsnagDeviceWithState deviceWithDictionary:event]; BugsnagUser *user = [self parseUser:event deviceAppHash:deviceAppHash deviceId:device.id]; - BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithMetadata:[event valueForKeyPath:@"user.config"]]; + BugsnagConfiguration *config = [[BugsnagConfiguration alloc] initWithDictionaryRepresentation:[event valueForKeyPath:@"user.config"]]; BugsnagAppWithState *app = [BugsnagAppWithState appWithDictionary:event config:config codeBundleId:self.codeBundleId]; - if (!app.type) { // Configuration.type does not get stored in the crash report at the time of writing. - app.type = [Bugsnag configuration].appType; - } BugsnagEvent *obj = [self initWithApp:app device:device handledState:handledState @@ -475,13 +478,9 @@ - (NSMutableDictionary *)parseOnCrashData:(NSDictionary *)report { @synthesize apiKey = _apiKey; - (NSString *)apiKey { - if (! _apiKey) { - _apiKey = Bugsnag.configuration.apiKey; - } return _apiKey; } - - (void)setApiKey:(NSString *)apiKey { if ([BugsnagConfiguration isValidApiKey:apiKey]) { _apiKey = apiKey; @@ -496,8 +495,7 @@ - (void)setApiKey:(NSString *)apiKey { - (BOOL)shouldBeSent { return [self.enabledReleaseStages containsObject:self.releaseStage] || - (self.enabledReleaseStages.count == 0 && - [[Bugsnag configuration] shouldSendReports]); + (self.enabledReleaseStages.count == 0); } - (NSArray *)serializeBreadcrumbs { diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagNotifier.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagNotifier.m index 09e93fa75b..e59034259d 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagNotifier.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagNotifier.m @@ -23,7 +23,7 @@ - (instancetype)init { #else self.name = @"Bugsnag Objective-C"; #endif - self.version = @"6.4.1"; + self.version = @"6.5.0"; self.url = @"https://github.com/bugsnag/bugsnag-cocoa"; self.dependencies = [NSMutableArray new]; } diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagSessionTrackingPayload.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagSessionTrackingPayload.h index 21034135c4..17420d96ab 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagSessionTrackingPayload.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagSessionTrackingPayload.h @@ -10,6 +10,7 @@ #import "BugsnagSession.h" @class BugsnagConfiguration; +@class BugsnagNotifier; @interface BugsnagSessionTrackingPayload : NSObject @@ -17,7 +18,8 @@ - (instancetype)initWithSessions:(NSArray *)sessions config:(BugsnagConfiguration *)config - codeBundleId:(NSString *)codeBundleId; + codeBundleId:(NSString *)codeBundleId + notifier:(BugsnagNotifier *)notifier; - (NSMutableDictionary *)toJson; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagSessionTrackingPayload.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagSessionTrackingPayload.m index 28721909b7..5e6c430119 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagSessionTrackingPayload.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagSessionTrackingPayload.m @@ -23,6 +23,7 @@ @interface BugsnagSessionTrackingPayload () @property (nonatomic) BugsnagConfiguration *config; @property(nonatomic, copy) NSString *codeBundleId; +@property (nonatomic) BugsnagNotifier *notifier; @end @implementation BugsnagSessionTrackingPayload @@ -30,11 +31,13 @@ @implementation BugsnagSessionTrackingPayload - (instancetype)initWithSessions:(NSArray *)sessions config:(BugsnagConfiguration *)config codeBundleId:(NSString *)codeBundleId + notifier:(BugsnagNotifier *)notifier { if (self = [super init]) { _sessions = sessions; _config = config; _codeBundleId = codeBundleId; + _notifier = notifier; } return self; } @@ -48,7 +51,7 @@ - (NSMutableDictionary *)toJson [sessionData addObject:[session toDictionary]]; } dict[@"sessions"] = sessionData; - dict[BSGKeyNotifier] = [[Bugsnag client].notifier toDict]; + dict[BSGKeyNotifier] = [self.notifier toDict]; // app/device data collection relies on KSCrash reports, // need to mimic the JSON structure here diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagThread+Private.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagThread+Private.h index 1caf2459d2..3616e22c00 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagThread+Private.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagThread+Private.h @@ -18,6 +18,8 @@ NS_ASSUME_NONNULL_BEGIN + (instancetype)threadFromJson:(NSDictionary *)json; +@property (readonly) NSString *crashInfoMessage; + + (NSDictionary *)enhanceThreadInfo:(NSDictionary *)thread depth:(NSUInteger)depth errorType:(nullable NSString *)errorType; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagThread.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagThread.m index cc2f73c081..fb68643999 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagThread.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Payload/BugsnagThread.m @@ -6,8 +6,9 @@ // Copyright © 2020 Bugsnag. All rights reserved. // -#import "BugsnagThread.h" +#import "BugsnagThread+Private.h" +#import "BSG_KSCrashReportFields.h" #import "BugsnagCollections.h" #import "BugsnagStackframe+Private.h" #import "BugsnagStacktrace+Private.h" @@ -56,13 +57,13 @@ - (instancetype)initWithId:(NSString *)id - (instancetype)initWithThread:(NSDictionary *)thread binaryImages:(NSArray *)binaryImages { if (self = [super init]) { - _errorReportingThread = [thread[@"crashed"] boolValue]; - self.id = [thread[@"index"] stringValue]; - self.type = BSGThreadTypeCocoa; - - NSArray *backtrace = thread[@"backtrace"][@"contents"]; + _errorReportingThread = [thread[@(BSG_KSCrashField_Crashed)] boolValue]; + _id = [thread[@(BSG_KSCrashField_Index)] stringValue]; + _type = BSGThreadTypeCocoa; + _crashInfoMessage = [thread[@(BSG_KSCrashField_CrashInfoMessage)] copy]; + NSArray *backtrace = thread[@(BSG_KSCrashField_Backtrace)][@(BSG_KSCrashField_Contents)]; BugsnagStacktrace *frames = [[BugsnagStacktrace alloc] initWithTrace:backtrace binaryImages:binaryImages]; - self.stacktrace = frames.trace; + _stacktrace = [frames.trace copy]; } return self; } diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagFileStore.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagFileStore.m index 66fe065a13..b938747f8e 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagFileStore.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagFileStore.m @@ -4,11 +4,12 @@ // #import "BugsnagFileStore.h" + +#import "BSGCachesDirectory.h" #import "BSG_KSCrashReportFields.h" #import "BSG_KSJSONCodecObjC.h" +#import "BugsnagLogger.h" #import "NSError+BSG_SimpleConstructor.h" -#import "BSG_KSLogger.h" -#import "BSGCachesDirectory.h" #pragma mark - Meta Data @@ -90,7 +91,7 @@ - (NSArray *)fileIds { NSFileManager *fm = [NSFileManager defaultManager]; NSArray *filenames = [fm contentsOfDirectoryAtPath:self.path error:&error]; if (filenames == nil) { - BSG_KSLOG_ERROR(@"Could not get contents of directory %@: %@", + bsg_log_err(@"Could not get contents of directory %@: %@", self.path, error); return nil; } @@ -105,7 +106,7 @@ - (NSArray *)fileIds { NSDictionary *fileAttribs = [fm attributesOfItemAtPath:fullPath error:&error]; if (fileAttribs == nil) { - BSG_KSLOG_ERROR(@"Could not read file attributes for %@: %@", + bsg_log_err(@"Could not read file attributes for %@: %@", fullPath, error); } else { FileStoreInfo *info = [FileStoreInfo fileStoreInfoWithId:fileId @@ -165,11 +166,11 @@ - (NSDictionary *)fileWithId:(NSString *)fileId { NSMutableDictionary *fileContents = [self readFile:[self pathToFileWithId:fileId] error:&error]; if (error != nil) { - BSG_KSLOG_ERROR(@"Encountered error loading file %@: %@", + bsg_log_err(@"Encountered error loading file %@: %@", fileId, error); } if (fileContents == nil) { - BSG_KSLOG_ERROR(@"Could not load file"); + bsg_log_err(@"Could not load file"); return nil; } return fileContents; @@ -181,7 +182,7 @@ - (void)deleteFileWithId:(NSString *)fileId { [[NSFileManager defaultManager] removeItemAtPath:filename error:&error]; if (error != nil) { - BSG_KSLOG_ERROR(@"Could not delete file %@: %@", filename, error); + bsg_log_err(@"Could not delete file %@: %@", filename, error); } } @@ -195,11 +196,11 @@ + (NSString *)findReportStorePath:(NSString *)customDirectory { [[BSGCachesDirectory cachesDirectory] stringByAppendingPathComponent:storePathEnd]; if ([storePath length] == 0) { - BSG_KSLOG_ERROR(@"Could not determine report files path."); + bsg_log_err(@"Could not determine report files path."); return nil; } if (![self ensureDirectoryExists:storePath]) { - BSG_KSLOG_ERROR(@"Store Directory does not exist."); + bsg_log_err(@"Store Directory does not exist."); return nil; } return storePath; @@ -214,7 +215,7 @@ + (BOOL)ensureDirectoryExists:(NSString *)path { withIntermediateDirectories:YES attributes:nil error:&error]) { - BSG_KSLOG_ERROR(@"Could not create directory %@: %@.", path, error); + bsg_log_err(@"Could not create directory %@: %@.", path, error); return NO; } } @@ -229,7 +230,7 @@ - (void)performOnFields:(NSArray *)fieldPath operation:(void (^)(id parent, id field))operation okIfNotFound:(BOOL)isOkIfNotFound { if (fieldPath.count == 0) { - BSG_KSLOG_ERROR(@"Unexpected end of field path"); + bsg_log_err(@"Unexpected end of field path"); return; } @@ -244,7 +245,7 @@ - (void)performOnFields:(NSArray *)fieldPath id field = file[currentField]; if (field == nil) { if (!isOkIfNotFound) { - BSG_KSLOG_ERROR(@"%@: No such field in file. Candidates are: %@", + bsg_log_err(@"%@: No such field in file. Candidates are: %@", currentField, file.allKeys); } return; @@ -300,7 +301,7 @@ - (NSMutableDictionary *)readFile:(NSString *)path error:error]; if (error != nil && *error != nil) { - BSG_KSLOG_ERROR(@"Error decoding JSON data from %@: %@", path, *error); + bsg_log_err(@"Error decoding JSON data from %@: %@", path, *error); fileContents[@BSG_KSCrashField_Incomplete] = @YES; } return fileContents; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagSessionFileStore.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagSessionFileStore.h index 6a5616c04b..3e9b3bcf1d 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagSessionFileStore.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagSessionFileStore.h @@ -9,7 +9,8 @@ #import "BugsnagSession.h" @interface BugsnagSessionFileStore : BugsnagFileStore -+ (BugsnagSessionFileStore *)storeWithPath:(NSString *)path; ++ (BugsnagSessionFileStore *)storeWithPath:(NSString *)path + maxPersistedSessions:(NSUInteger)maxPersistedSessions; - (void)write:(BugsnagSession *)session; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagSessionFileStore.m b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagSessionFileStore.m index 95951b56f7..3ab62d019e 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagSessionFileStore.m +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/Storage/BugsnagSessionFileStore.m @@ -5,17 +5,33 @@ #import "BugsnagSessionFileStore.h" -#import "BSG_KSLogger.h" #import "BSGJSONSerialization.h" +#import "BugsnagLogger.h" #import "BugsnagSession+Private.h" static NSString *const kSessionStoreSuffix = @"-Session-"; +@interface BugsnagSessionFileStore () + +@property NSUInteger maxPersistedSessions; + +@end + @implementation BugsnagSessionFileStore -+ (BugsnagSessionFileStore *)storeWithPath:(NSString *)path { ++ (BugsnagSessionFileStore *)storeWithPath:(NSString *)path + maxPersistedSessions:(NSUInteger)maxPersistedSessions { return [[self alloc] initWithPath:path - filenameSuffix:kSessionStoreSuffix]; + maxPersistedSessions:maxPersistedSessions]; +} + +- (instancetype) initWithPath:(NSString *)path + maxPersistedSessions:(NSUInteger)maxPersistedSessions { + if ((self = [super initWithPath:path + filenameSuffix:kSessionStoreSuffix])) { + _maxPersistedSessions = maxPersistedSessions; + } + return self; } - (void)write:(BugsnagSession *)session { @@ -27,9 +43,11 @@ - (void)write:(BugsnagSession *)session { NSData *json = [BSGJSONSerialization dataWithJSONObject:dict options:0 error:&error]; if (error != nil || ![json writeToFile:filepath atomically:YES]) { - BSG_KSLOG_ERROR(@"Failed to write session %@", error); + bsg_log_err(@"Failed to write session %@", error); return; } + + [self pruneFilesLeaving:(int)self.maxPersistedSessions]; } diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/include/Bugsnag/BugsnagConfiguration.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/include/Bugsnag/BugsnagConfiguration.h index 844f4406e4..b6fa258e3d 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/include/Bugsnag/BugsnagConfiguration.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/include/Bugsnag/BugsnagConfiguration.h @@ -149,6 +149,20 @@ typedef BOOL (^BugsnagOnSessionBlock)(BugsnagSession *_Nonnull session); */ @property(readwrite, retain, nullable) NSSet *redactedKeys; +/** + * A set of strings and / or NSRegularExpression objects that determine which errors should + * be discarded based on their `errorClass`. + * + * Comparisons are case sensitive. + * + * OnError / OnSendError blocks will not be called for discarded errors. + * + * Some examples of errorClass are: Objective-C exception names like "NSRangeException", + * signal names like "SIGABRT", mach exception names like "EXC_BREAKPOINT", and Swift + * error names like "Fatal error". + */ +@property(readwrite, copy, nullable) NSSet *discardClasses; + /** * A general summary of what was occuring in the application */ @@ -204,6 +218,22 @@ typedef BOOL (^BugsnagOnSessionBlock)(BugsnagSession *_Nonnull session); @property(retain, nullable) NSString *appType; +/** + * Sets the maximum number of events which will be stored. Once the threshold is reached, + * the oldest events will be deleted. + * + * By default, 12 events are stored: this can be amended up to a maximum of 100. + */ +@property (nonatomic) NSUInteger maxPersistedEvents; + +/** + * Sets the maximum number of sessions which will be stored. Once the threshold is reached, + * the oldest sessions will be deleted. + * + * By default, 32 sessions are stored: this can be amended up to a maximum of 100. + */ +@property (nonatomic) NSUInteger maxPersistedSessions; + /** * Sets the maximum number of breadcrumbs which will be stored. Once the threshold is reached, * the oldest breadcrumbs will be deleted. diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/include/Bugsnag/BugsnagEvent.h b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/include/Bugsnag/BugsnagEvent.h index a3c85a307d..9c07c3c64c 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/include/Bugsnag/BugsnagEvent.h +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Bugsnag/include/Bugsnag/BugsnagEvent.h @@ -62,7 +62,7 @@ typedef NS_ENUM(NSUInteger, BSGSeverity) { /** * A per-event override for the apiKey. - * - Reads default to the BugsnagConfiguration apiKey value unless explicitly set. + * - The default value of nil results in the BugsnagConfiguration apiKey being used. * - Writes are not persisted to BugsnagConfiguration. */ @property(readwrite, copy, nullable) NSString *apiKey; diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/CHANGELOG.md b/packages/react-native/ios/vendor/bugsnag-cocoa/CHANGELOG.md index b525a2f6d6..0a85d4a026 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/CHANGELOG.md +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/CHANGELOG.md @@ -1,6 +1,27 @@ Changelog ========= +## 6.5.0 (2021-01-06) + +### Enhancements + +* Errors may now be discarded based on their `errorClass` using the new `discardClasses` configuration option. + [#938](https://github.com/bugsnag/bugsnag-cocoa/pull/938) + +* The maxiumum number of persisted errors / events may now be configured using the new `maxPersistedEvents` configuration option. + [#936](https://github.com/bugsnag/bugsnag-cocoa/pull/936) + +* The maxiumum number of persisted sessions may now be configured using the new `maxPersistedSessions` configuration option. + [#943](https://github.com/bugsnag/bugsnag-cocoa/pull/943) + +* Bugsnag log messages are now prefixed with `[Bugsnag]` for easier searching & filtering. + [#955](https://github.com/bugsnag/bugsnag-cocoa/pull/955) + +## Bug fixes + +* Fix reliability of Swift fatal error message reporting. + [#948](https://github.com/bugsnag/bugsnag-cocoa/pull/948) + ## 6.4.1 (2020-12-14) ### Bug fixes diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/Framework/Info.plist b/packages/react-native/ios/vendor/bugsnag-cocoa/Framework/Info.plist index a75e8d8718..6662460650 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/Framework/Info.plist +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/Framework/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 6.4.1 + 6.5.0 CFBundleVersion 1 diff --git a/packages/react-native/ios/vendor/bugsnag-cocoa/VERSION b/packages/react-native/ios/vendor/bugsnag-cocoa/VERSION index 4c77920fd2..f22d756da3 100644 --- a/packages/react-native/ios/vendor/bugsnag-cocoa/VERSION +++ b/packages/react-native/ios/vendor/bugsnag-cocoa/VERSION @@ -1 +1 @@ -6.4.1 +6.5.0 From 753d0438da8211d693cf73268f3b08b5ca3daed6 Mon Sep 17 00:00:00 2001 From: Nick Dowell Date: Wed, 6 Jan 2021 15:00:27 +0000 Subject: [PATCH 2/3] deps(react-native): Use private headers instead of redeclaring interfaces --- .../BugsnagEventDeserializer.m | 76 +++---------------- .../BugsnagReactNative/BugsnagReactNative.m | 30 +------- .../BugsnagReactNativeEmitter.m | 13 +--- .../BugsnagReactNativePlugin.m | 9 +-- 4 files changed, 21 insertions(+), 107 deletions(-) diff --git a/packages/react-native/ios/BugsnagReactNative/BugsnagEventDeserializer.m b/packages/react-native/ios/BugsnagReactNative/BugsnagEventDeserializer.m index 6500b46510..c46a6d1d82 100644 --- a/packages/react-native/ios/BugsnagReactNative/BugsnagEventDeserializer.m +++ b/packages/react-native/ios/BugsnagReactNative/BugsnagEventDeserializer.m @@ -8,80 +8,28 @@ #import "BugsnagEventDeserializer.h" +#import "Bugsnag+Private.h" +#import "BugsnagAppWithState+Private.h" +#import "BugsnagBreadcrumb+Private.h" +#import "BugsnagClient+Private.h" +#import "BugsnagDeviceWithState+Private.h" +#import "BugsnagError+Private.h" +#import "BugsnagEvent+Private.h" +#import "BugsnagHandledState.h" +#import "BugsnagSessionTracker+Private.h" #import "BugsnagStacktrace.h" - -BSGSeverity BSGParseSeverity(NSString *severity); - -@interface Bugsnag () -+ (id)client; -+ (BugsnagConfiguration *)configuration; -@end - -@interface BugsnagClient() -@property id sessionTracker; -@property BugsnagMetadata *metadata; -@end - -@interface BugsnagError () - -- (instancetype)initWithErrorClass:(NSString *)errorClass - errorMessage:(NSString *)errorMessage - errorType:(BSGErrorType)errorType - stacktrace:(NSArray *)stacktrace; - -@end - -@interface BugsnagMetadata () -@end - -@interface BugsnagHandledState: NSObject -- (instancetype)initWithSeverityReason:(NSUInteger)severityReason - severity:(BSGSeverity)severity - unhandled:(BOOL)unhandled - unhandledOverridden:(BOOL)unhandledOverridden - attrValue:(NSString *)attrValue; -+ (NSUInteger)severityReasonFromString:(NSString *)string; -@end - -@interface BugsnagAppWithState() -+ (BugsnagAppWithState *)appFromJson:(NSDictionary *)json; -@end - -@interface BugsnagDeviceWithState() -+ (BugsnagDeviceWithState *)deviceFromJson:(NSDictionary *)json; -@end - -@interface BugsnagUser() -- (instancetype)initWithDictionary:(NSDictionary *)dict; -@end - -@interface BugsnagThread () -+ (instancetype)threadFromJson:(NSDictionary *)json; -@end +#import "BugsnagThread+Private.h" +#import "BugsnagUser+Private.h" @interface BugsnagEvent () -- (instancetype)initWithApp:(BugsnagAppWithState *)app - device:(BugsnagDeviceWithState *)device - handledState:(BugsnagHandledState *)handledState - user:(BugsnagUser *)user - metadata:(BugsnagMetadata *)metadata - breadcrumbs:(NSArray *)breadcrumbs - errors:(NSArray *)errors - threads:(NSArray *)threads - session:(BugsnagSession *)session; -- (NSDictionary *)toJson; - (void)attachCustomStacktrace:(NSArray *)frames withType:(NSString *)type; @end -@interface BugsnagBreadcrumb () -+ (instancetype)breadcrumbFromDict:(NSDictionary *)dict; -@end - @implementation BugsnagEventDeserializer - (BugsnagEvent *)deserializeEvent:(NSDictionary *)payload { BugsnagClient *client = [Bugsnag client]; - BugsnagSession *session = [client.sessionTracker valueForKey:@"runningSession"]; + BugsnagSession *session = client.sessionTracker.runningSession; BugsnagMetadata *metadata = [[BugsnagMetadata alloc] initWithDictionary:payload[@"metadata"]]; BugsnagHandledState *handledState = [self deserializeHandledState:payload]; diff --git a/packages/react-native/ios/BugsnagReactNative/BugsnagReactNative.m b/packages/react-native/ios/BugsnagReactNative/BugsnagReactNative.m index 14db55b577..312b152a6c 100644 --- a/packages/react-native/ios/BugsnagReactNative/BugsnagReactNative.m +++ b/packages/react-native/ios/BugsnagReactNative/BugsnagReactNative.m @@ -1,24 +1,12 @@ -#import "Bugsnag.h" -#import "BugsnagClient.h" #import "BugsnagReactNative.h" + +#import "Bugsnag+Private.h" +#import "BugsnagClient+Private.h" #import "BugsnagReactNativeEmitter.h" #import "BugsnagConfigSerializer.h" #import "BugsnagEventDeserializer.h" -@interface BugsnagClient () -- (NSDictionary *)collectAppWithState; -- (NSDictionary *)collectDeviceWithState; -- (NSArray *)collectBreadcrumbs; -- (NSArray *)collectThreads:(BOOL)unhandled; -@property id notifier; -@property id sessionTracker; -@property BugsnagMetadata *metadata; -@end - @interface Bugsnag () -+ (BugsnagClient *)client; -+ (BOOL)bugsnagStarted; -+ (BugsnagConfiguration *)configuration; + (void)updateCodeBundleId:(NSString *)codeBundleId; + (void)notifyInternal:(BugsnagEvent *_Nonnull)event block:(BOOL (^_Nonnull)(BugsnagEvent *_Nonnull))block; @@ -26,18 +14,6 @@ + (void)addRuntimeVersionInfo:(NSString *)info withKey:(NSString *)key; @end -@interface BugsnagMetadata () -@end - -@interface BugsnagEvent () -- (instancetype _Nonnull)initWithErrorName:(NSString *_Nonnull)name - errorMessage:(NSString *_Nonnull)message - configuration:(BugsnagConfiguration *_Nonnull)config - metadata:(BugsnagMetadata *_Nullable)metadata - handledState:(BugsnagHandledState *_Nonnull)handledState - session:(BugsnagSession *_Nullable)session; -@end - @interface BugsnagReactNative () @property (nonatomic) BugsnagConfigSerializer *configSerializer; @end diff --git a/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativeEmitter.m b/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativeEmitter.m index 020a057afe..fdc3490c31 100644 --- a/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativeEmitter.m +++ b/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativeEmitter.m @@ -1,18 +1,11 @@ #import "BugsnagReactNativeEmitter.h" -#import "Bugsnag.h" -#import "BugsnagClient.h" -@interface BugsnagStateEvent: NSObject -@property NSString *type; -@property id data; -@end +#import "Bugsnag+Private.h" +#import "BugsnagClient.h" +#import "BugsnagStateEvent.h" typedef void (^BugsnagObserverBlock)(BugsnagStateEvent *_Nonnull event); -@interface Bugsnag () -+ (BugsnagClient *)client; -@end - @interface BugsnagClient () - (void)addObserverWithBlock:(BugsnagObserverBlock _Nonnull)block; - (void)removeObserverWithBlock:(BugsnagObserverBlock _Nonnull)block; diff --git a/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativePlugin.m b/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativePlugin.m index fa7f672294..6ab363d971 100644 --- a/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativePlugin.m +++ b/packages/react-native/ios/BugsnagReactNative/BugsnagReactNativePlugin.m @@ -1,12 +1,9 @@ +#import "BugsnagReactNativePlugin.h" + #import "Bugsnag.h" -#import "BugsnagClient.h" +#import "BugsnagClient+Private.h" #import "BugsnagConfiguration.h" #import "BugsnagError.h" -#import "BugsnagReactNativePlugin.h" - -@interface BugsnagClient () -@property(nonatomic, readwrite, retain) BugsnagConfiguration * configuration; -@end @interface BugsnagReactNativePlugin () @end From 9547f8ea4ef7f599f5c754f690ca96d31da8c36e Mon Sep 17 00:00:00 2001 From: Nick Dowell Date: Thu, 7 Jan 2021 08:07:37 +0000 Subject: [PATCH 3/3] Update changelog for bugsnag-cocoa v6.5.0 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ffed025f3c..2f95b38c73 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ ### Changed - (expo): Add support for Expo SDK v40 [#1219](https://github.com/bugsnag/bugsnag-js/pull/1219) +- (react-native): Update bugsnag-cocoa to v6.5.0 + - Add `errorClass` configuration option. [bugsnag-cocoa#938](https://github.com/bugsnag/bugsnag-cocoa/pull/938) + - Add `maxPersistedEvents` configuration option. [bugsnag-cocoa#936](https://github.com/bugsnag/bugsnag-cocoa/pull/936) + - Add `maxPersistedSessions` configuration option. [bugsnag-cocoa#943](https://github.com/bugsnag/bugsnag-cocoa/pull/943) + - Add `[Bugsnag]` prefix to log messages. [bugsnag-cocoa#955](https://github.com/bugsnag/bugsnag-cocoa/pull/955) + - Fix reliability of Swift fatal error message reporting. [bugsnag-cocoa#948](https://github.com/bugsnag/bugsnag-cocoa/pull/948) ## v7.5.5 (2020-12-14)