Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- Detect development builds via provisioning profile and debugger attachment (#7702)
- Keep replayType as `buffer` for Session Replay triggered by an error (#7804)
- Fix race condition in scope observer notifications causing EXC_BAD_ACCESS during cold launch (#7807)
- Harden SentryCrash JSON floating-point encoding (#7802)
Comment thread
denrase marked this conversation as resolved.
Outdated

## 9.10.0

Expand Down
38 changes: 29 additions & 9 deletions Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.c
Original file line number Diff line number Diff line change
Expand Up @@ -317,34 +317,54 @@ sentrycrashjson_addFloatingPointElement(
if (isnan(value)) {
return sentrycrashjson_addNullElement(context, name);
}
if (isinf(value)) {
int result = sentrycrashjson_beginElement(context, name);
unlikely_if(result != SentryCrashJSON_OK) { return result; }
return value > 0 ? addJSONData(context, "1e999", 5) : addJSONData(context, "-1e999", 6);
Comment thread
denrase marked this conversation as resolved.
}

char buff[50];
int written = snprintf(buff, sizeof(buff), "%lg", value);
if (written < 0) {
return SentryCrashJSON_ERROR_INVALID_CHARACTER;
} else if (written >= (int)sizeof(buff)) {
return SentryCrashJSON_ERROR_DATA_TOO_LONG;
}
int result = sentrycrashjson_beginElement(context, name);
unlikely_if(result != SentryCrashJSON_OK) { return result; }
char buff[50];
snprintf(buff, sizeof(buff), "%lg", value);
return addJSONData(context, buff, (int)strlen(buff));
return addJSONData(context, buff, written);
}

int
sentrycrashjson_addIntegerElement(
SentryCrashJSONEncodeContext *const context, const char *const name, int64_t value)
{
char buff[30];
Comment thread
philprime marked this conversation as resolved.
Outdated
int written = snprintf(buff, sizeof(buff), "%" PRId64, value);
if (written < 0) {
return SentryCrashJSON_ERROR_INVALID_CHARACTER;
} else if (written >= (int)sizeof(buff)) {
return SentryCrashJSON_ERROR_DATA_TOO_LONG;
}
int result = sentrycrashjson_beginElement(context, name);
unlikely_if(result != SentryCrashJSON_OK) { return result; }
char buff[30];
snprintf(buff, sizeof(buff), "%" PRId64, value);
return addJSONData(context, buff, (int)strlen(buff));
return addJSONData(context, buff, written);
}

int
sentrycrashjson_addUIntegerElement(
SentryCrashJSONEncodeContext *const context, const char *const name, uint64_t value)
{
char buff[30];
Comment thread
philprime marked this conversation as resolved.
Outdated
int written = snprintf(buff, sizeof(buff), "%" PRIu64, value);
if (written < 0) {
return SentryCrashJSON_ERROR_INVALID_CHARACTER;
} else if (written >= (int)sizeof(buff)) {
return SentryCrashJSON_ERROR_DATA_TOO_LONG;
}
int result = sentrycrashjson_beginElement(context, name);
unlikely_if(result != SentryCrashJSON_OK) { return result; }
char buff[30];
snprintf(buff, sizeof(buff), "%" PRIu64, value);
return addJSONData(context, buff, (int)strlen(buff));
return addJSONData(context, buff, written);
}

int
Expand Down
78 changes: 78 additions & 0 deletions Tests/SentryTests/SentryCrash/SentryCrashJSONCodec_Tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,84 @@ - (void)testSerializeDeserializeNANDouble
XCTAssertTrue([[result objectAtIndex:0] isKindOfClass:[NSNull class]]);
}

- (void)testSerializeDeserializePositiveInfinityFloat
{
NSError *error = (NSError *)self;
NSString *expected = @"[1e999]";
float infValue = INFINITY;
id original = [NSArray arrayWithObjects:[NSNumber numberWithFloat:infValue], nil];

NSString *jsonString = toString([SentryCrashJSONCodec encode:original
options:SentryCrashJSONEncodeOptionSorted
error:&error]);
XCTAssertNotNil(jsonString, @"");
XCTAssertNil(error, @"");
XCTAssertEqualObjects(jsonString, expected, @"");
id result = [SentryCrashJSONCodec decode:toData(jsonString) options:0 error:&error];
XCTAssertNotNil(result, @"");
XCTAssertNil(error, @"");
XCTAssertTrue(isinf([[result objectAtIndex:0] doubleValue]), @"Should decode back to infinity");
}

- (void)testSerializeDeserializeNegativeInfinityFloat
{
NSError *error = (NSError *)self;
NSString *expected = @"[-1e999]";
float infValue = -INFINITY;
id original = [NSArray arrayWithObjects:[NSNumber numberWithFloat:infValue], nil];

NSString *jsonString = toString([SentryCrashJSONCodec encode:original
options:SentryCrashJSONEncodeOptionSorted
error:&error]);
XCTAssertNotNil(jsonString, @"");
XCTAssertNil(error, @"");
XCTAssertEqualObjects(jsonString, expected, @"");
id result = [SentryCrashJSONCodec decode:toData(jsonString) options:0 error:&error];
XCTAssertNotNil(result, @"");
XCTAssertNil(error, @"");
XCTAssertTrue(isinf([[result objectAtIndex:0] doubleValue]), @"Should decode back to infinity");
XCTAssertTrue([[result objectAtIndex:0] doubleValue] < 0, @"Should be negative infinity");
}

- (void)testSerializeDeserializePositiveInfinityDouble
{
NSError *error = (NSError *)self;
NSString *expected = @"[1e999]";
double infValue = (double)INFINITY;
id original = [NSArray arrayWithObjects:[NSNumber numberWithDouble:infValue], nil];

NSString *jsonString = toString([SentryCrashJSONCodec encode:original
options:SentryCrashJSONEncodeOptionSorted
error:&error]);
XCTAssertNotNil(jsonString, @"");
XCTAssertNil(error, @"");
XCTAssertEqualObjects(jsonString, expected, @"");
id result = [SentryCrashJSONCodec decode:toData(jsonString) options:0 error:&error];
XCTAssertNotNil(result, @"");
XCTAssertNil(error, @"");
XCTAssertTrue(isinf([[result objectAtIndex:0] doubleValue]), @"Should decode back to infinity");
}

- (void)testSerializeDeserializeNegativeInfinityDouble
{
NSError *error = (NSError *)self;
NSString *expected = @"[-1e999]";
double infValue = -(double)INFINITY;
id original = [NSArray arrayWithObjects:[NSNumber numberWithDouble:infValue], nil];

NSString *jsonString = toString([SentryCrashJSONCodec encode:original
options:SentryCrashJSONEncodeOptionSorted
error:&error]);
XCTAssertNotNil(jsonString, @"");
XCTAssertNil(error, @"");
XCTAssertEqualObjects(jsonString, expected, @"");
id result = [SentryCrashJSONCodec decode:toData(jsonString) options:0 error:&error];
XCTAssertNotNil(result, @"");
XCTAssertNil(error, @"");
XCTAssertTrue(isinf([[result objectAtIndex:0] doubleValue]), @"Should decode back to infinity");
XCTAssertTrue([[result objectAtIndex:0] doubleValue] < 0, @"Should be negative infinity");
}

- (void)testSerializeDeserializeChar
{
NSError *error = (NSError *)self;
Expand Down
Loading