]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
sd-varlink: add new sd_varlink_error_is_invalid_parameter() helper
authorLennart Poettering <lennart@poettering.net>
Tue, 15 Oct 2024 11:40:24 +0000 (13:40 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 15 Oct 2024 12:15:21 +0000 (14:15 +0200)
src/libsystemd/libsystemd.sym
src/libsystemd/sd-varlink/sd-varlink.c
src/systemd/sd-varlink.h
src/test/test-varlink.c

index b3f46f90f19ff25f6624f8dcf3c0dcbe6b82256d..e1836da08ff0dd6e5ea1c9e74922f8ed987dd4ad 100644 (file)
@@ -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;
index 70615bb3e3b6db7e3b07224d8ee96cea1c189c09..fb42e3205da3861ae963af3276449e51034482c6 100644 (file)
@@ -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);
+}
index 4c943d5389d2efb6e88a285c759bafc7e8dc7e2d..4596561ed3be6ee4bdc9c9d9896140e496bc9436 100644 (file)
@@ -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);
index 17a78633cc144ae4bf13cd0f108f5445f586c697..cafe98871bbc3489aea619c8d797d23266331604 100644 (file)
@@ -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);