]> git.ipfire.org Git - thirdparty/json-c.git/commitdiff
reject out-of-range double in get_int64/get_uint64 940/head
authorJavid Khan <dxbjavid@gmail.com>
Mon, 6 Jul 2026 12:37:09 +0000 (18:07 +0530)
committerJavid Khan <dxbjavid@gmail.com>
Mon, 6 Jul 2026 12:37:09 +0000 (18:07 +0530)
json_object.c
tests/test_int_get.c

index e9fcc686dcd293be17f1b525488e9a9b9b6fb003..ca4c089f69d88f0802ef34040a27d7d9bb5db72e 100644 (file)
@@ -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;
index e694fb36a43f5d496b85c96820b193842af37312..3c41a828e20bf3898e03f7e6f0ef59d0ebb049f3 100644 (file)
@@ -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");