Skip to content

Commit

Permalink
Json value conversion validation
Browse files Browse the repository at this point in the history
  • Loading branch information
ximtech committed Dec 2, 2023
1 parent e1675b5 commit 10ad2e3
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 13 deletions.
40 changes: 28 additions & 12 deletions JSON.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,40 @@ static inline void terminateJsonString(JSONTokener *jsonTokener) {
*jsonTokener->jsonStringEnd = JSON_NULL_CHAR;
}

static inline bool isJsonIntegerValid(int32_t number, const char *valuePointer, const char *endPointer) {
static inline bool isValidParsedLength(const char *valuePointer, const char *endPointer, uint32_t valueLength) {
return endPointer == NULL || *endPointer == '\0' || endPointer - valuePointer == valueLength;
}

static inline bool isJsonIntegerValid(int32_t number,
const char *valuePointer,
const char *endPointer,
uint32_t expectedValueLength) {
return (valuePointer == endPointer) || // no digits found
(errno == ERANGE && number == LONG_MIN) || // underflow occurred
(errno == ERANGE && number == LONG_MAX) // overflow occurred
(errno == ERANGE && number == LONG_MAX) || // overflow occurred
!isValidParsedLength(valuePointer, endPointer, expectedValueLength)
? false : true;
}

static inline bool isJsonLongValid(int64_t number, const char *valuePointer, const char *endPointer) {
return (valuePointer == endPointer) || // no digits found
static inline bool isJsonLongValid(int64_t number,
const char *valuePointer,
const char *endPointer,
uint32_t expectedValueLength) {
return (valuePointer == endPointer) || // no digits found
(errno == ERANGE && number == LLONG_MIN) || // underflow occurred
(errno == ERANGE && number == LLONG_MAX) // overflow occurred
(errno == ERANGE && number == LLONG_MAX) || // overflow occurred
!isValidParsedLength(valuePointer, endPointer, expectedValueLength)
? false : true;
}

static inline bool isJsonDoubleNumberValid(double number, const char *valuePointer, const char *endPointer) {
static inline bool isJsonDoubleNumberValid(double number,
const char *valuePointer,
const char *endPointer,
uint32_t expectedValueLength) {
return (valuePointer == endPointer) || // no digits found
(errno == ERANGE && number == DBL_MIN) || // underflow occurred
(errno == ERANGE && number == DBL_MAX) // overflow occurred
(errno == ERANGE && number == DBL_MAX) || // overflow occurred
!isValidParsedLength(valuePointer, endPointer, expectedValueLength)
? false : true;
}

Expand Down Expand Up @@ -748,7 +764,7 @@ static JSONType detectJsonValueType(char *jsonTextValue, uint32_t valueLength) {
char *endPointer = NULL;
if (isDoubleValue) {
double doubleNumber = strtod(jsonTextValue, &endPointer); // try to parse double number
if (isJsonDoubleNumberValid(doubleNumber, jsonTextValue, endPointer)) {
if (isJsonDoubleNumberValid(doubleNumber, jsonTextValue, endPointer, valueLength)) {
if (doubleNumber != 0 || valueLength == 1) {
return JSON_DOUBLE;
}
Expand All @@ -758,17 +774,17 @@ static JSONType detectJsonValueType(char *jsonTextValue, uint32_t valueLength) {
errno = 0;
endPointer = NULL;
int32_t intNumber = strtol(jsonTextValue, &endPointer, 10); // try to parse decimal number
if (isJsonIntegerValid(intNumber, jsonTextValue, endPointer)) {
if ((intNumber != 0 || valueLength == 1) && !isalpha((int) *endPointer)) { // check that 0 value is not an error and also no additional chars
if (isJsonIntegerValid(intNumber, jsonTextValue, endPointer, valueLength)) {
if (intNumber != 0 || valueLength == 1) { // check that 0 value is not an error and also no additional chars
return JSON_INTEGER;
}
}

errno = 0;
endPointer = NULL;
int64_t longNumber = strtoll(jsonTextValue, &endPointer, 10);
if (isJsonLongValid(longNumber, jsonTextValue, endPointer)) {
if ((longNumber != 0 || valueLength == 1) && !isalpha((int) *endPointer)) {
if (isJsonLongValid(longNumber, jsonTextValue, endPointer, valueLength)) {
if (longNumber != 0 || valueLength == 1) {
return JSON_LONG;
}
}
Expand Down
3 changes: 2 additions & 1 deletion Tests/JSON/JSONCreateTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ static MunitResult createJsonArrayTest(const MunitParameter params[], void *data
JSONObject innerObject = createJsonObject(&innerArrayTokener);
jsonObjectPut(&innerObject, "key1", "12345");
jsonObjectPut(&innerObject, "key2", "256MB");
jsonObjectPut(&innerObject, "key3", "6462150918:AAGGejPL9-F0CONZy2dwCn_uET96tYjQDA4");
jsonArrayAddObject(&jsonArray, &innerObject);

char resBuffer[256] = {0};
jsonArrayToString(&jsonArray, resBuffer);
assert_string_equal("[\"text\",12.22,222,true,null,234123423543,[1,2,3],{\"key1\":12345,\"key2\":\"256MB\"}]", resBuffer);
assert_string_equal("[\"text\",12.22,222,true,null,234123423543,[1,2,3],{\"key1\":12345,\"key2\":\"256MB\",\"key3\":\"6462150918:AAGGejPL9-F0CONZy2dwCn_uET96tYjQDA4\"}]", resBuffer);

deleteJSONArray(&jsonArray);
return MUNIT_OK;
Expand Down

0 comments on commit 10ad2e3

Please sign in to comment.