From: Javid Khan Date: Mon, 6 Jul 2026 12:37:09 +0000 (+0530) Subject: reject out-of-range double in get_int64/get_uint64 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F940%2Fhead;p=thirdparty%2Fjson-c.git reject out-of-range double in get_int64/get_uint64 --- diff --git a/json_object.c b/json_object.c index e9fcc68..ca4c089 100644 --- a/json_object.c +++ b/json_object.c @@ -996,9 +996,10 @@ int64_t json_object_get_int64(const struct json_object *jso) } } 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; @@ -1049,9 +1050,10 @@ uint64_t json_object_get_uint64(const struct json_object *jso) } } 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; diff --git a/tests/test_int_get.c b/tests/test_int_get.c index e694fb3..3c41a82 100644 --- a/tests/test_int_get.c +++ b/tests/test_int_get.c @@ -65,6 +65,8 @@ int main(int argc, char **argv) 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); @@ -73,6 +75,8 @@ int main(int argc, char **argv) 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");