json-util: add json_dispatch_job_id() dispatcher for job IDs
Job IDs are uint32_t values that are always >= 1 (the manager's ID counter starts at 1 and wraps from UINT32_MAX back to 1, never assigning 0). Add a dedicated dispatch function that validates this constraint, rejecting 0 and treating null as "unset" (0). Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -796,6 +796,27 @@ int json_dispatch_access_mode(const char *name, sd_json_variant *variant, sd_jso
|
||||
return 0;
|
||||
}
|
||||
|
||||
int json_dispatch_job_id(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata) {
|
||||
uint32_t *id = ASSERT_PTR(userdata);
|
||||
uint32_t k;
|
||||
int r;
|
||||
|
||||
if (sd_json_variant_is_null(variant)) {
|
||||
*id = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_json_dispatch_uint32(name, variant, flags, &k);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (k == 0)
|
||||
return json_log(variant, flags, SYNTHETIC_ERRNO(EINVAL), "JSON field '%s' is not a valid job ID.", strna(name));
|
||||
|
||||
*id = k;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int json_variant_compare(sd_json_variant *a, sd_json_variant *b) {
|
||||
int r;
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ int json_dispatch_ifindex(const char *name, sd_json_variant *variant, sd_json_di
|
||||
int json_dispatch_log_level(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int json_dispatch_strv_environment(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int json_dispatch_access_mode(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
int json_dispatch_job_id(const char *name, sd_json_variant *variant, sd_json_dispatch_flags_t flags, void *userdata);
|
||||
|
||||
static inline int json_variant_unbase64_iovec(sd_json_variant *v, struct iovec *ret) {
|
||||
return sd_json_variant_unbase64(v, ret ? &ret->iov_base : NULL, ret ? &ret->iov_len : NULL);
|
||||
|
||||
@@ -1569,6 +1569,69 @@ TEST(access_mode) {
|
||||
&mm), ERANGE);
|
||||
}
|
||||
|
||||
TEST(job_id) {
|
||||
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
|
||||
|
||||
ASSERT_OK(sd_json_parse("{\"a\": 1, \"b\": 4294967295, \"c\": null}",
|
||||
/* flags= */ 0,
|
||||
&v,
|
||||
/* reterr_line= */ NULL,
|
||||
/* reterr_column= */ NULL));
|
||||
|
||||
struct {
|
||||
uint32_t a, b, c;
|
||||
} data = { 99, 99, 99 };
|
||||
|
||||
ASSERT_OK(sd_json_dispatch(
|
||||
v,
|
||||
(const sd_json_dispatch_field[]) {
|
||||
{ "a", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_job_id, voffsetof(data, a), 0 },
|
||||
{ "b", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_job_id, voffsetof(data, b), 0 },
|
||||
{ "c", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_job_id, voffsetof(data, c), 0 },
|
||||
{},
|
||||
},
|
||||
/* flags= */ 0,
|
||||
&data));
|
||||
|
||||
ASSERT_EQ(data.a, UINT32_C(1));
|
||||
ASSERT_EQ(data.b, UINT32_MAX);
|
||||
ASSERT_EQ(data.c, UINT32_C(0));
|
||||
|
||||
/* Zero is not a valid job ID */
|
||||
sd_json_variant_unrefp(&v);
|
||||
ASSERT_OK(sd_json_parse("{\"a\": 0}",
|
||||
/* flags= */ 0,
|
||||
&v,
|
||||
/* reterr_line= */ NULL,
|
||||
/* reterr_column= */ NULL));
|
||||
|
||||
ASSERT_ERROR(sd_json_dispatch(
|
||||
v,
|
||||
(const sd_json_dispatch_field[]) {
|
||||
{ "a", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_job_id, voffsetof(data, a), 0 },
|
||||
{},
|
||||
},
|
||||
/* flags= */ 0,
|
||||
&data), EINVAL);
|
||||
|
||||
/* Negative values are not valid */
|
||||
sd_json_variant_unrefp(&v);
|
||||
ASSERT_OK(sd_json_parse("{\"a\": -1}",
|
||||
/* flags= */ 0,
|
||||
&v,
|
||||
/* reterr_line= */ NULL,
|
||||
/* reterr_column= */ NULL));
|
||||
|
||||
ASSERT_ERROR(sd_json_dispatch(
|
||||
v,
|
||||
(const sd_json_dispatch_field[]) {
|
||||
{ "a", _SD_JSON_VARIANT_TYPE_INVALID, json_dispatch_job_id, voffsetof(data, a), 0 },
|
||||
{},
|
||||
},
|
||||
/* flags= */ 0,
|
||||
&data), EINVAL);
|
||||
}
|
||||
|
||||
static void test_json_variant_compare_one(const char *a, const char *b, int expected) {
|
||||
int r;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user