summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2024-10-15 13:40:24 +0200
committerLennart Poettering <lennart@poettering.net>2024-10-15 14:15:21 +0200
commit12641ecd67875b7bf18db06c0afa40c37d804750 (patch)
tree1fbaf4210daf90a6f98a35a6cff7d2c6cf78310f
parentnetwork: add AF_TO_ADDRESS_FAMILY() helper (diff)
downloadsystemd-12641ecd67875b7bf18db06c0afa40c37d804750.tar.xz
systemd-12641ecd67875b7bf18db06c0afa40c37d804750.zip
sd-varlink: add new sd_varlink_error_is_invalid_parameter() helper
Diffstat (limited to '')
-rw-r--r--src/libsystemd/libsystemd.sym1
-rw-r--r--src/libsystemd/sd-varlink/sd-varlink.c20
-rw-r--r--src/systemd/sd-varlink.h2
-rw-r--r--src/test/test-varlink.c57
4 files changed, 77 insertions, 3 deletions
diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym
index b3f46f90f1..e1836da08f 100644
--- a/src/libsystemd/libsystemd.sym
+++ b/src/libsystemd/libsystemd.sym
@@ -975,6 +975,7 @@ global:
sd_varlink_error_errno;
sd_varlink_error_invalid_parameter;
sd_varlink_error_invalid_parameter_name;
+ sd_varlink_error_is_invalid_parameter;
sd_varlink_error_to_errno;
sd_varlink_errorb;
sd_varlink_flush;
diff --git a/src/libsystemd/sd-varlink/sd-varlink.c b/src/libsystemd/sd-varlink/sd-varlink.c
index 70615bb3e3..fb42e3205d 100644
--- a/src/libsystemd/sd-varlink/sd-varlink.c
+++ b/src/libsystemd/sd-varlink/sd-varlink.c
@@ -4112,3 +4112,23 @@ _public_ int sd_varlink_error_to_errno(const char *error, sd_json_variant *param
return -EBADR; /* Catch-all */
}
+
+_public_ int sd_varlink_error_is_invalid_parameter(const char *error, sd_json_variant *parameter, const char *name) {
+
+ /* Returns true if the specified error result is an invalid parameter error for the parameter 'name' */
+
+ if (!streq_ptr(error, SD_VARLINK_ERROR_INVALID_PARAMETER))
+ return false;
+
+ if (!name)
+ return true;
+
+ if (!sd_json_variant_is_object(parameter))
+ return false;
+
+ sd_json_variant *e = sd_json_variant_by_key(parameter, "parameter");
+ if (!e || !sd_json_variant_is_string(e))
+ return false;
+
+ return streq(sd_json_variant_string(e), name);
+}
diff --git a/src/systemd/sd-varlink.h b/src/systemd/sd-varlink.h
index 4c943d5389..4596561ed3 100644
--- a/src/systemd/sd-varlink.h
+++ b/src/systemd/sd-varlink.h
@@ -266,6 +266,8 @@ int sd_varlink_invocation(sd_varlink_invocation_flags_t flags);
int sd_varlink_error_to_errno(const char *error, sd_json_variant *parameters);
+int sd_varlink_error_is_invalid_parameter(const char *error, sd_json_variant *parameter, const char *name);
+
/* Define helpers so that __attribute__((cleanup(sd_varlink_unrefp))) and similar may be used. */
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_varlink, sd_varlink_unref);
_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_varlink, sd_varlink_close_unref);
diff --git a/src/test/test-varlink.c b/src/test/test-varlink.c
index 17a78633cc..cafe98871b 100644
--- a/src/test/test-varlink.c
+++ b/src/test/test-varlink.c
@@ -326,7 +326,7 @@ static int block_fd_handler(sd_event_source *s, int fd, uint32_t revents, void *
return 0;
}
-int main(int argc, char *argv[]) {
+TEST(chat) {
_cleanup_(sd_event_source_unrefp) sd_event_source *block_event = NULL;
_cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL;
_cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *c = NULL;
@@ -337,8 +337,6 @@ int main(int argc, char *argv[]) {
pthread_t t;
const char *sp;
- test_setup_logging(LOG_DEBUG);
-
assert_se(mkdtemp_malloc("/tmp/varlink-test-XXXXXX", &tmpdir) >= 0);
sp = strjoina(tmpdir, "/socket");
@@ -377,6 +375,59 @@ int main(int argc, char *argv[]) {
assert_se(sd_event_loop(e) >= 0);
assert_se(pthread_join(t, NULL) == 0);
+}
+
+static int method_invalid(sd_varlink *link, sd_json_variant *parameters, sd_varlink_method_flags_t flags, void *userdata) {
+ int r;
+
+ sd_json_dispatch_field table[] = {
+ { "iexist", SD_JSON_VARIANT_STRING, sd_json_dispatch_const_string, 0, SD_JSON_MANDATORY },
+ {}
+ };
+
+ const char *p = NULL;
+ r = sd_varlink_dispatch(link, parameters, table, &p);
+ if (r != 0)
+ return r;
+
+ assert_not_reached();
+}
+
+static int reply_invalid(sd_varlink *link, sd_json_variant *parameters, const char *error_id, sd_varlink_reply_flags_t flags, void *userdata) {
+ assert(sd_varlink_error_is_invalid_parameter(error_id, parameters, "idontexist"));
+ assert(sd_event_exit(sd_varlink_get_event(link), EXIT_SUCCESS) >= 0);
return 0;
}
+
+TEST(invalid_parameter) {
+ _cleanup_(sd_event_unrefp) sd_event *e = NULL;
+ assert_se(sd_event_default(&e) >= 0);
+
+ _cleanup_(sd_varlink_server_unrefp) sd_varlink_server *s = NULL;
+ assert_se(sd_varlink_server_new(&s, 0) >= 0);
+
+ assert_se(sd_varlink_server_attach_event(s, e, 0) >= 0);
+
+ assert_se(sd_varlink_server_bind_method(s, "foo.mytest.Invalid", method_invalid) >= 0);
+
+ int connfd[2];
+ assert_se(socketpair(AF_UNIX, SOCK_STREAM|SOCK_NONBLOCK|SOCK_CLOEXEC, 0, connfd) >= 0);
+ assert_se(sd_varlink_server_add_connection(s, connfd[0], /* ret= */ NULL) >= 0);
+
+ _cleanup_(sd_varlink_unrefp) sd_varlink *c = NULL;
+ assert_se(sd_varlink_connect_fd(&c, connfd[1]) >= 0);
+
+ assert_se(sd_varlink_attach_event(c, e, 0) >= 0);
+
+ assert_se(sd_varlink_bind_reply(c, reply_invalid) >= 0);
+
+ assert_se(sd_varlink_invokebo(c, "foo.mytest.Invalid",
+ SD_JSON_BUILD_PAIR_STRING("iexist", "foo"),
+ SD_JSON_BUILD_PAIR_STRING("idontexist", "bar")) >= 0);
+
+
+ assert_se(sd_event_loop(e) >= 0);
+}
+
+DEFINE_TEST_MAIN(LOG_DEBUG);