}
}
case json_type_double:
- // INT64_MAX can't be exactly represented as a double
- // so cast to tell the compiler it's ok to round up.
- if (JC_DOUBLE_C(jso)->c_double > (double)INT64_MAX)
+ // INT64_MAX can't be exactly represented as a double, so it
+ // rounds up to (double)(INT64_MAX+1). Use >= so that value is
+ // rejected rather than cast to int64_t, which would be UB.
+ if (JC_DOUBLE_C(jso)->c_double >= (double)INT64_MAX)
{
errno = ERANGE;
return INT64_MAX;
}
}
case json_type_double:
- // UINT64_MAX can't be exactly represented as a double
- // so cast to tell the compiler it's ok to round up.
- if (JC_DOUBLE_C(jso)->c_double > (double)UINT64_MAX)
+ // UINT64_MAX can't be exactly represented as a double, so it
+ // rounds up to (double)(UINT64_MAX+1). Use >= so that value is
+ // rejected rather than cast to uint64_t, which would be UB.
+ if (JC_DOUBLE_C(jso)->c_double >= (double)UINT64_MAX)
{
errno = ERANGE;
return UINT64_MAX;
CHECK_GET_INT64(N_DBL(INFINITY), INT64_MAX && errno == ERANGE);
CHECK_GET_INT64(N_DBL(-INFINITY), INT64_MIN && errno == ERANGE);
CHECK_GET_INT64(N_DBL(NAN), INT64_MIN && errno == EINVAL);
+ // (double)INT64_MAX rounds up to 2^63, which is one past INT64_MAX
+ CHECK_GET_INT64(N_DBL(9223372036854775808.0), INT64_MAX && errno == ERANGE);
printf("INT64 GET PASSED\n");
CHECK_GET_UINT64(N_U64(UINT64_MAX), UINT64_MAX && errno == 0);
CHECK_GET_UINT64(N_DBL(INFINITY), UINT64_MAX && errno == ERANGE);
CHECK_GET_UINT64(N_DBL(-INFINITY), 0 && errno == ERANGE);
CHECK_GET_UINT64(N_DBL(NAN), 0 && errno == EINVAL);
+ // (double)UINT64_MAX rounds up to 2^64, which is one past UINT64_MAX
+ CHECK_GET_UINT64(N_DBL(18446744073709551616.0), UINT64_MAX && errno == ERANGE);
printf("UINT64 GET PASSED\n");
printf("PASSED\n");