Skip to content

Commit

Permalink
fix: Use uint64 instead of double in crash report (#2642)
Browse files Browse the repository at this point in the history
Follow up on #2631 to use uint64 instead of double for encoding
and decoding crash reports.
  • Loading branch information
philipphofmann authored Jan 24, 2023
1 parent 83d2d84 commit d10ae0c
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 6 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ This version adds a dependency on Swift. We renamed the default branch from `mas

### Fixes

- Support uint64 in crash reports (#2631)
- Support uint64 in crash reports (#2631, #2642)
- Always fetch view hierarchy on the main thread (#2629)
- Carthage Xcode 14 compatibility issue (#2636)
- Crash in CppException Monitor (#2639)
Expand Down
2 changes: 1 addition & 1 deletion Sources/SentryCrash/Recording/SentryCrashReport.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ static void
addUIntegerElement(
const SentryCrashReportWriter *const writer, const char *const key, const uint64_t value)
{
sentrycrashjson_addIntegerElement(getJsonContext(writer), key, (int64_t)value);
sentrycrashjson_addUIntegerElement(getJsonContext(writer), key, value);
}

static void
Expand Down
29 changes: 29 additions & 0 deletions Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,17 @@ sentrycrashjson_addIntegerElement(
return addJSONData(context, buff, (int)strlen(buff));
}

int
sentrycrashjson_addUIntegerElement(
SentryCrashJSONEncodeContext *const context, const char *const name, uint64_t value)
{
int result = sentrycrashjson_beginElement(context, name);
unlikely_if(result != SentryCrashJSON_OK) { return result; }
char buff[30];
sprintf(buff, "%" PRIu64, value);
return addJSONData(context, buff, (int)strlen(buff));
}

int
sentrycrashjson_addNullElement(SentryCrashJSONEncodeContext *const context, const char *const name)
{
Expand Down Expand Up @@ -1217,6 +1228,12 @@ decodeElement(const char *const name, SentryCrashJSONDecodeContext *context)
}
}

if (!isFPChar(*context->bufferPtr) && !isOverflow) {
if (sign == 1 && accum <= ULLONG_MAX) {
return context->callbacks->onUIntegerElement(name, accum, context->userData);
}
}

while (context->bufferPtr < context->bufferEnd && isFPChar(*context->bufferPtr)) {
context->bufferPtr++;
}
Expand Down Expand Up @@ -1354,6 +1371,16 @@ addJSONFromFile_onIntegerElement(const char *const name, const int64_t value, vo
return result;
}

static int
addJSONFromFile_onUIntegerElement(
const char *const name, const uint64_t value, void *const userData)
{
JSONFromFileContext *context = (JSONFromFileContext *)userData;
int result = sentrycrashjson_addUIntegerElement(context->encodeContext, name, value);
context->updateDecoderCallback(context);
return result;
}

static int
addJSONFromFile_onNullElement(const char *const name, void *const userData)
{
Expand Down Expand Up @@ -1423,6 +1450,7 @@ sentrycrashjson_addJSONFromFile(SentryCrashJSONEncodeContext *const encodeContex
.onEndData = addJSONFromFile_onEndData,
.onFloatingPointElement = addJSONFromFile_onFloatingPointElement,
.onIntegerElement = addJSONFromFile_onIntegerElement,
.onUIntegerElement = addJSONFromFile_onUIntegerElement,
.onNullElement = addJSONFromFile_onNullElement,
.onStringElement = addJSONFromFile_onStringElement,
};
Expand Down Expand Up @@ -1480,6 +1508,7 @@ sentrycrashjson_addJSONElement(SentryCrashJSONEncodeContext *const encodeContext
.onEndData = addJSONFromFile_onEndData,
.onFloatingPointElement = addJSONFromFile_onFloatingPointElement,
.onIntegerElement = addJSONFromFile_onIntegerElement,
.onUIntegerElement = addJSONFromFile_onUIntegerElement,
.onNullElement = addJSONFromFile_onNullElement,
.onStringElement = addJSONFromFile_onStringElement,
};
Expand Down
26 changes: 26 additions & 0 deletions Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodec.h
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,19 @@ int sentrycrashjson_addBooleanElement(
int sentrycrashjson_addIntegerElement(
SentryCrashJSONEncodeContext *context, const char *name, int64_t value);

/** Add an unsigned integer element.
*
* @param context The encoding context.
*
* @param name The element's name.
*
* @param value The element's value.
*
* @return SentryCrashJSON_OK if the process was successful.
*/
int sentrycrashjson_addUIntegerElement(
SentryCrashJSONEncodeContext *context, const char *name, uint64_t value);

/** Add a floating point element.
*
* @param context The encoding context.
Expand Down Expand Up @@ -416,6 +429,19 @@ typedef struct SentryCrashJSONDecodeCallbacks {
*/
int (*onIntegerElement)(const char *name, int64_t value, void *userData);

/** Called when an unsigned integer element is decoded.
*
* @param name The element's name.
*
* @param value The element's value.
*
* @param userData Data that was specified when calling
* sentrycrashjson_decode().
*
* @return SentryCrashJSON_OK if decoding should continue.
*/
int (*onUIntegerElement)(const char *name, uint64_t value, void *userData);

/** Called when a null element is decoded.
*
* @param name The element's name.
Expand Down
10 changes: 10 additions & 0 deletions Sources/SentryCrash/Recording/Tools/SentryCrashJSONCodecObjC.m
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ - (id)initWithEncodeOptions:(SentryCrashJSONEncodeOption)encodeOptions
self.callbacks->onEndData = onEndData;
self.callbacks->onFloatingPointElement = onFloatingPointElement;
self.callbacks->onIntegerElement = onIntegerElement;
self.callbacks->onUIntegerElement = onUIntegerElement;
self.callbacks->onNullElement = onNullElement;
self.callbacks->onStringElement = onStringElement;

Expand Down Expand Up @@ -231,6 +232,15 @@ - (void)dealloc
return onElement(codec, name, element);
}

static int
onUIntegerElement(const char *const cName, const uint64_t value, void *const userData)
{
NSString *name = stringFromCString(cName);
id element = [NSNumber numberWithUnsignedLongLong:value];
SentryCrashJSONCodec *codec = (__bridge SentryCrashJSONCodec *)userData;
return onElement(codec, name, element);
}

static int
onNullElement(const char *const cName, void *const userData)
{
Expand Down
17 changes: 13 additions & 4 deletions Tests/SentryTests/SentryCrash/SentryCrashJSONCodec_Tests.m
Original file line number Diff line number Diff line change
Expand Up @@ -1296,15 +1296,24 @@ - (void)testDeserializeArray_64IntMax
XCTAssertEqual([result[0] longLongValue], value);
}

- (void)testDeserializeArrayUIntMax_UsesDouble
- (void)testDeserializeArrayIntMaxPlusOne_UsesUInt
{
uint64_t value = (uint64_t)LLONG_MAX + 1;
NSString *jsonString = [NSString stringWithFormat:@"[%llu]", value];

NSArray<NSNumber *> *result = [self decode:jsonString];

XCTAssertEqual([result[0] unsignedLongLongValue], value);
}

- (void)testDeserializeArrayUIntMax_UsesUInt
{
uint64_t value = ULLONG_MAX;
NSString *jsonString = [NSString stringWithFormat:@"[%llu]", value];

NSArray<NSNumber *> *result = [self decode:jsonString];

XCTAssertNotEqual([result[0] unsignedLongLongValue], value);
XCTAssertEqual([result[0] doubleValue], [@(value) doubleValue]);
XCTAssertEqual([result[0] unsignedLongLongValue], value);
}

- (void)testDeserializeArray_NegativeLLONG_MIN_plusOne_UsesDouble
Expand Down Expand Up @@ -1566,7 +1575,7 @@ - (void)testAddJSONFromBigFile
{
NSString *savedFilename = [self.tempPath stringByAppendingPathComponent:@"big.json"];
id savedObject = @{
@"an_array" : @[ @1, @2, @3, @4 ],
@"an_array" : @[ @1, @2, @3, @4, @1.3, @(YES), @(LLONG_MIN), @(ULLONG_MAX) ],
@"lines" : @[
@"I cannot describe to you my sensations on the near prospect of my undertaking.",
@"It is impossible to communicate to you a conception of the trembling sensation, half pleasurable and half fearful, with which I am preparing to depart.",
Expand Down

0 comments on commit d10ae0c

Please sign in to comment.