Explicitly handle NaN values when converting to int

Json objects of type double with the value NaN could cause undefined
behavior when casting double to int in `json_object_get_int`.
This commit is contained in:
Simon Resch
2024-11-14 13:47:18 +01:00
parent 565f181f65
commit 8c13801f2c
5 changed files with 51 additions and 8 deletions

View File

@@ -36,6 +36,7 @@ int main(int argc, char **argv)
\"array_with_zero\": [ 0 ],\n\
\"empty_object\": {},\n\
\"nonempty_object\": { \"a\": 123 },\n\
\"nan\": NaN,\n\
}";
/* Note: 2147483649 = INT_MAX + 2 */
/* Note: 9223372036854775809 = INT64_MAX + 2 */
@@ -62,6 +63,7 @@ int main(int argc, char **argv)
getit(new_obj, "array_with_zero");
getit(new_obj, "empty_object");
getit(new_obj, "nonempty_object");
getit(new_obj, "nan");
// Now check the behaviour of the json_object_is_type() function.
printf("\n================================\n");
@@ -75,6 +77,7 @@ int main(int argc, char **argv)
checktype(new_obj, "int64_number");
checktype(new_obj, "negative_number");
checktype(new_obj, "a_null");
checktype(new_obj, "nan");
json_object_put(new_obj);

View File

@@ -12,6 +12,7 @@ Parsed input: {
"array_with_zero": [ 0 ],
"empty_object": {},
"nonempty_object": { "a": 123 },
"nan": NaN,
}
Result is not NULL
new_obj.string_of_digits json_object_get_type()=string
@@ -92,6 +93,12 @@ new_obj.nonempty_object json_object_get_int64()=0
new_obj.nonempty_object json_object_get_uint64()=0
new_obj.nonempty_object json_object_get_boolean()=0
new_obj.nonempty_object json_object_get_double()=0.000000
new_obj.nan json_object_get_type()=double
new_obj.nan json_object_get_int()=-2147483648
new_obj.nan json_object_get_int64()=-9223372036854775808
new_obj.nan json_object_get_uint64()=0
new_obj.nan json_object_get_boolean()=1
new_obj.nan json_object_get_double()=nan
================================
json_object_is_type: null,boolean,double,int,object,array,string
@@ -104,3 +111,4 @@ new_obj.boolean_false : 0,1,0,0,0,0,0
new_obj.int64_number : 0,0,0,1,0,0,0
new_obj.negative_number : 0,0,0,1,0,0,0
new_obj.a_null : 1,0,0,0,0,0,0
new_obj.nan : 0,0,1,0,0,0,0

View File

@@ -4,6 +4,7 @@
#include <assert.h>
#include <stdio.h>
#include <errno.h>
#include <math.h>
#include "json.h"
@@ -25,6 +26,7 @@
#define N_I64 json_object_new_int64
#define N_U64 json_object_new_uint64
#define N_STR json_object_new_string
#define N_DBL json_object_new_double
int main(int argc, char **argv)
{
@@ -45,6 +47,8 @@ int main(int argc, char **argv)
CHECK_GET_INT(N_I64(INT64_MIN), INT32_MIN && errno == 0);
CHECK_GET_INT(N_STR(I64_MAX_S), INT32_MAX && errno == 0);
CHECK_GET_INT(N_STR(I64_MIN_S), INT32_MIN && errno == 0);
CHECK_GET_INT(N_DBL(NAN), INT32_MIN && errno == EINVAL);
printf("INT GET PASSED\n");
CHECK_GET_INT64(N_I64(INT64_MAX), INT64_MAX && errno == 0);
@@ -53,11 +57,13 @@ int main(int argc, char **argv)
CHECK_GET_INT64(N_STR(I64_MIN_S), INT64_MIN && errno == 0);
CHECK_GET_INT64(N_STR(I64_OVER), INT64_MAX && errno == ERANGE);
CHECK_GET_INT64(N_STR(I64_UNDER), INT64_MIN && errno == ERANGE);
CHECK_GET_INT64(N_DBL(NAN), INT64_MIN && errno == EINVAL);
printf("INT64 GET PASSED\n");
CHECK_GET_UINT64(N_U64(UINT64_MAX), UINT64_MAX && errno == 0);
CHECK_GET_UINT64(N_U64(-1), UINT64_MAX && errno == 0);
CHECK_GET_UINT64(N_STR(U64_OUT_S), UINT64_MAX && errno == ERANGE);
CHECK_GET_UINT64(N_DBL(NAN), 0 && errno == EINVAL);
printf("UINT64 GET PASSED\n");
printf("PASSED\n");