json_object_get_int/int64/uint64() now sets errno to ERANGE when the source value
can't be represented in the target type.
{
case json_type_int:
/* Make sure we return the correct values for out of range numbers. */
- if (cint64 <= INT32_MIN)
+ if (cint64 < INT32_MIN)
+ {
+ errno = ERANGE;
return INT32_MIN;
- if (cint64 >= INT32_MAX)
+ }
+ if (cint64 > INT32_MAX)
+ {
+ errno = ERANGE;
return INT32_MAX;
+ }
return (int32_t)cint64;
case json_type_double:
cdouble = JC_DOUBLE_C(jso)->c_double;
- if (cdouble <= INT32_MIN)
+ if (cdouble < INT32_MIN)
+ {
+ errno = ERANGE;
return INT32_MIN;
- if (cdouble >= INT32_MAX)
+ }
+ if (cdouble > INT32_MAX)
+ {
+ errno = ERANGE;
return INT32_MAX;
+ }
if (isnan(cdouble))
{
errno = EINVAL;
{
case json_object_int_type_int64: return jsoint->cint.c_int64;
case json_object_int_type_uint64:
- if (jsoint->cint.c_uint64 >= INT64_MAX)
+ if (jsoint->cint.c_uint64 > INT64_MAX)
+ {
+ errno = ERANGE;
return INT64_MAX;
+ }
return (int64_t)jsoint->cint.c_uint64;
default: json_abort("invalid cint_type");
}
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)
+ if (JC_DOUBLE_C(jso)->c_double > (double)INT64_MAX)
+ {
+ errno = ERANGE;
return INT64_MAX;
- if (JC_DOUBLE_C(jso)->c_double <= INT64_MIN)
+ }
+ if (JC_DOUBLE_C(jso)->c_double < (double)INT64_MIN)
+ {
+ errno = ERANGE;
return INT64_MIN;
+ }
if (isnan(JC_DOUBLE_C(jso)->c_double))
{
errno = EINVAL;
{
case json_object_int_type_int64:
if (jsoint->cint.c_int64 < 0)
+ {
+ errno = ERANGE;
return 0;
+ }
return (uint64_t)jsoint->cint.c_int64;
case json_object_int_type_uint64: return jsoint->cint.c_uint64;
default: json_abort("invalid cint_type");
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)
+ if (JC_DOUBLE_C(jso)->c_double > (double)UINT64_MAX)
+ {
+ errno = ERANGE;
return UINT64_MAX;
+ }
if (JC_DOUBLE_C(jso)->c_double < 0)
+ {
+ errno = ERANGE;
return 0;
+ }
if (isnan(JC_DOUBLE_C(jso)->c_double))
{
errno = EINVAL;
* which return INT32_MIN and the errno is set to EINVAL.
* Strings will be parsed as an integer. If no conversion exists then 0 is
* returned and errno is set to EINVAL. null is equivalent to 0 (no error values
- * set)
+ * set).
+ * Sets errno to ERANGE if the value exceeds the range of int.
*
* Note that integers are stored internally as 64-bit values.
* If the value of too big or too small to fit into 32-bit, INT32_MAX or
* which return INT64_MIN and the errno is set to EINVAL.
* Strings will be parsed as an int64. If no conversion exists then 0 is
* returned and errno is set to EINVAL. null is equivalent to 0 (no error values
- * set)
+ * set).
+ * Sets errno to ERANGE if the value exceeds the range of int64.
*
* NOTE: Set errno to 0 directly before a call to this function to determine
* whether or not conversion was successful (it does not clear the value for
* which return 0 and the errno is set to EINVAL.
* Strings will be parsed as an uint64. If no conversion exists then 0 is
* returned and errno is set to EINVAL. null is equivalent to 0 (no error values
- * set)
+ * set).
+ * Sets errno to ERANGE if the value exceeds the range of uint64.
*
* NOTE: Set errno to 0 directly before a call to this function to determine
* whether or not conversion was successful (it does not clear the value for
#include "json.h"
+#define I32_MAX_S "2147483647"
+#define I32_MIN_S "-2147483648"
#define I64_MAX_S "9223372036854775807"
#define I64_OVER "9223372036854775808"
#define I64_MIN_S "-9223372036854775808"
CHECK_GET_INT(N_I64(INT32_MAX), INT32_MAX && errno == 0);
CHECK_GET_INT(N_I64(INT32_MIN), INT32_MIN && errno == 0);
- CHECK_GET_INT(N_I64(INT64_MAX), INT32_MAX && errno == 0);
- 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_I64(INT64_MAX), INT32_MAX && errno == ERANGE);
+ CHECK_GET_INT(N_I64(INT64_MIN), INT32_MIN && errno == ERANGE);
+ CHECK_GET_INT(N_STR(I32_MAX_S), INT32_MAX && errno == 0);
+ CHECK_GET_INT(N_STR(I32_MIN_S), INT32_MIN && errno == 0);
+ CHECK_GET_INT(N_STR(I64_MAX_S), INT32_MAX && errno == ERANGE);
+ CHECK_GET_INT(N_STR(I64_MIN_S), INT32_MIN && errno == ERANGE);
+ CHECK_GET_INT(N_DBL(INFINITY), INT32_MAX && errno == ERANGE);
+ CHECK_GET_INT(N_DBL(-INFINITY), INT32_MIN && errno == ERANGE);
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);
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(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);
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(INFINITY), UINT64_MAX && errno == ERANGE);
+ CHECK_GET_UINT64(N_DBL(-INFINITY), 0 && errno == ERANGE);
CHECK_GET_UINT64(N_DBL(NAN), 0 && errno == EINVAL);
printf("UINT64 GET PASSED\n");