diff --git a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSJSONCodecObjC.m b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSJSONCodecObjC.m index b687d6e30..91e8cc8c7 100644 --- a/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSJSONCodecObjC.m +++ b/Bugsnag/KSCrash/Source/KSCrash/Recording/Tools/BSG_KSJSONCodecObjC.m @@ -29,6 +29,7 @@ #import "BSG_KSJSONCodec.h" #import "BSG_RFC3339DateTool.h" #import "NSError+BSG_SimpleConstructor.h" +#import "BSG_KSLogger.h" @interface BSG_KSJSONCodec () @@ -487,20 +488,28 @@ int bsg_ksjsoncodecobjc_i_encodeObject(BSG_KSJSONCodec *codec, id object, + (NSData *)encode:(id)object options:(BSG_KSJSONEncodeOption)encodeOptions error:(NSError *__autoreleasing *)error { - NSMutableData *data = [NSMutableData data]; - BSG_KSJSONEncodeContext JSONContext; - bsg_ksjsonbeginEncode( - &JSONContext, encodeOptions & BSG_KSJSONEncodeOptionPretty, - bsg_ksjsoncodecobjc_i_addJSONData, (__bridge void *)data); - BSG_KSJSONCodec *codec = - [self codecWithEncodeOptions:encodeOptions decodeOptions:0]; - - int result = - bsg_ksjsoncodecobjc_i_encodeObject(codec, object, NULL, &JSONContext); - if (error != nil) { - *error = codec.error; + @try { + NSMutableData *data = [NSMutableData data]; + BSG_KSJSONEncodeContext JSONContext; + bsg_ksjsonbeginEncode( + &JSONContext, encodeOptions & BSG_KSJSONEncodeOptionPretty, + bsg_ksjsoncodecobjc_i_addJSONData, (__bridge void *)data); + BSG_KSJSONCodec *codec = + [self codecWithEncodeOptions:encodeOptions decodeOptions:0]; + + int result = + bsg_ksjsoncodecobjc_i_encodeObject(codec, object, NULL, &JSONContext); + if (error != nil) { + *error = codec.error; + } + return result == BSG_KSJSON_OK ? data : nil; + } @catch (NSException *exception) { + BSG_KSLOG_ERROR(@"Could not encode JSON object: %@", exception.description); + if (error != nil) { + *error = [NSError bsg_errorWithDomain:@"KSJSONCodecObjC" code:0 description:exception.description]; + } + return nil; } - return result == BSG_KSJSON_OK ? data : nil; } + (id)decode:(NSData *)JSONData @@ -511,6 +520,10 @@ + (id)decode:(NSData *)JSONData @try { result = [NSJSONSerialization JSONObjectWithData:JSONData options:0 error:error]; } @catch (NSException *exception) { + BSG_KSLOG_ERROR(@"Could not decode JSON object: %@", exception.description); + if (error != nil) { + *error = [NSError bsg_errorWithDomain:@"KSJSONCodecObjC" code:0 description:exception.description]; + } result = @{}; } return result; diff --git a/CHANGELOG.md b/CHANGELOG.md index ca3ea936b..1508ebffb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,14 +3,20 @@ Changelog ## TBD -## Enhancements +### Bug fixes + +* Catch and report unexpected exceptions when (de)serializing JSON data rather + than crashing. + [856](https://github.com/bugsnag/bugsnag-cocoa/pull/856) + +### Enhancements * Reduced the CPU and memory impact of leaving breadcrumbs. [853](https://github.com/bugsnag/bugsnag-cocoa/pull/853) ## 6.2.2 (2020-10-21) -## Enhancements +### Enhancements * Support "foreground" duration in MacOS as well. [848](https://github.com/bugsnag/bugsnag-cocoa/pull/848) @@ -25,7 +31,7 @@ Changelog ## 6.2.1 (2020-10-15) -## Bug fixes +### Bug fixes * Changed synchronization method when responding to dynamic library image events to a dispatch queue, which is a more bulletproof and battle-hardened approach. @@ -54,7 +60,7 @@ Changelog ## 6.1.7 (2020-10-01) -## Bug fixes +### Bug fixes * Re-enabled the `Require Only App-Extension-Safe API` build setting [823](https://github.com/bugsnag/bugsnag-cocoa/pull/823)