diff --git a/src/libsystemd/sd-json/json-util.c b/src/libsystemd/sd-json/json-util.c index 556d4c786b..6f42239b91 100644 --- a/src/libsystemd/sd-json/json-util.c +++ b/src/libsystemd/sd-json/json-util.c @@ -31,6 +31,11 @@ int json_dispatch_unhex_iovec(const char *name, sd_json_variant *variant, sd_jso size_t sz; int r; + if (sd_json_variant_is_null(variant)) { + iovec_done(iov); + return 0; + } + if (!sd_json_variant_is_string(variant)) return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name)); @@ -49,6 +54,11 @@ int json_dispatch_unbase64_iovec(const char *name, sd_json_variant *variant, sd_ size_t sz; int r; + if (sd_json_variant_is_null(variant)) { + iovec_done(iov); + return 0; + } + if (!sd_json_variant_is_string(variant)) return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a string.", strna(name)); @@ -68,6 +78,11 @@ int json_dispatch_byte_array_iovec(const char *name, sd_json_variant *variant, s assert(variant); + if (sd_json_variant_is_null(variant)) { + iovec_done(iov); + return 0; + } + if (!sd_json_variant_is_array(variant)) return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not an array.", strna(name)); @@ -169,6 +184,11 @@ int json_dispatch_in_addr(const char *name, sd_json_variant *variant, sd_json_di _cleanup_(iovec_done) struct iovec iov = {}; int r; + if (sd_json_variant_is_null(variant)) { + *address = (struct in_addr) {}; + return 0; + } + r = json_dispatch_byte_array_iovec(name, variant, flags, &iov); if (r < 0) return r; diff --git a/src/libsystemd/sd-json/sd-json.c b/src/libsystemd/sd-json/sd-json.c index 79cfa4cc60..b13960897e 100644 --- a/src/libsystemd/sd-json/sd-json.c +++ b/src/libsystemd/sd-json/sd-json.c @@ -5292,6 +5292,11 @@ _public_ int sd_json_dispatch_stdbool(const char *name, sd_json_variant *variant assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *b = false; + return 0; + } + if (!sd_json_variant_is_boolean(variant)) return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a boolean.", strna(name)); @@ -5305,6 +5310,11 @@ _public_ int sd_json_dispatch_intbool(const char *name, sd_json_variant *variant assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *b = false; + return 0; + } + if (!sd_json_variant_is_boolean(variant)) return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a boolean.", strna(name)); @@ -5336,6 +5346,11 @@ _public_ int sd_json_dispatch_int64(const char *name, sd_json_variant *variant, assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *i = -1; + return 0; + } + /* Also accept numbers formatted as string, to increase compatibility with less capable JSON * implementations that cannot do 64bit integers. */ if (sd_json_variant_is_string(variant) && safe_atoi64(sd_json_variant_string(variant), i) >= 0) @@ -5354,6 +5369,11 @@ _public_ int sd_json_dispatch_uint64(const char *name, sd_json_variant *variant, assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *u = UINT64_MAX; + return 0; + } + /* Since 64bit values (in particular unsigned ones) in JSON are problematic, let's also accept them * formatted as strings. If this is not desired make sure to set the .type field in * sd_json_dispatch_field to SD_JSON_UNSIGNED rather than _SD_JSON_VARIANT_TYPE_INVALID, so that @@ -5377,6 +5397,11 @@ _public_ int sd_json_dispatch_uint32(const char *name, sd_json_variant *variant, assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *u = UINT32_MAX; + return 0; + } + r = sd_json_dispatch_uint64(name, variant, flags, &u64); if (r < 0) return r; @@ -5399,6 +5424,11 @@ _public_ int sd_json_dispatch_int32(const char *name, sd_json_variant *variant, assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *i = -1; + return 0; + } + r = sd_json_dispatch_int64(name, variant, flags, &i64); if (r < 0) return r; @@ -5421,6 +5451,11 @@ _public_ int sd_json_dispatch_int16(const char *name, sd_json_variant *variant, assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *i = -1; + return 0; + } + r = sd_json_dispatch_int64(name, variant, flags, &i64); if (r < 0) return r; @@ -5440,6 +5475,11 @@ _public_ int sd_json_dispatch_uint16(const char *name, sd_json_variant *variant, assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *u = UINT16_MAX; + return 0; + } + r = sd_json_dispatch_uint64(name, variant, flags, &u64); if (r < 0) return r; @@ -5459,6 +5499,11 @@ _public_ int sd_json_dispatch_int8(const char *name, sd_json_variant *variant, s assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *i = -1; + return 0; + } + r = sd_json_dispatch_int64(name, variant, flags, &i64); if (r < 0) return r; @@ -5478,6 +5523,11 @@ _public_ int sd_json_dispatch_uint8(const char *name, sd_json_variant *variant, assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *u = UINT8_MAX; + return 0; + } + r = sd_json_dispatch_uint64(name, variant, flags, &u64); if (r < 0) return r; @@ -5495,6 +5545,11 @@ _public_ int sd_json_dispatch_double(const char *name, sd_json_variant *variant, assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *d = NAN; + return 0; + } + /* Note, this will take care of parsing NaN, -Infinity, Infinity for us */ if (sd_json_variant_is_string(variant) && safe_atod(sd_json_variant_string(variant), d) >= 0) return 0; @@ -5514,6 +5569,11 @@ _public_ int sd_json_dispatch_string(const char *name, sd_json_variant *variant, assert_return(variant, -EINVAL); assert_return(userdata, -EINVAL); + if (sd_json_variant_is_null(variant)) { + *s = mfree(*s); + return 0; + } + r = sd_json_dispatch_const_string(name, variant, flags, &n); if (r < 0) return r;