1 /* SPDX-License-Identifier: LGPL-2.1+ */
11 #include <dbus/dbus.h>
16 #include "alloc-util.h"
18 #include "bus-label.h"
19 #include "bus-message.h"
27 static void test_bus_path_encode_unique(void) {
28 _cleanup_free_
char *a
= NULL
, *b
= NULL
, *c
= NULL
, *d
= NULL
, *e
= NULL
;
30 assert_se(bus_path_encode_unique(NULL
, "/foo/bar", "some.sender", "a.suffix", &a
) >= 0 && streq_ptr(a
, "/foo/bar/some_2esender/a_2esuffix"));
31 assert_se(bus_path_decode_unique(a
, "/foo/bar", &b
, &c
) > 0 && streq_ptr(b
, "some.sender") && streq_ptr(c
, "a.suffix"));
32 assert_se(bus_path_decode_unique(a
, "/bar/foo", &d
, &d
) == 0 && !d
);
33 assert_se(bus_path_decode_unique("/foo/bar/onlyOneSuffix", "/foo/bar", &d
, &d
) == 0 && !d
);
34 assert_se(bus_path_decode_unique("/foo/bar/_/_", "/foo/bar", &d
, &e
) > 0 && streq_ptr(d
, "") && streq_ptr(e
, ""));
37 static void test_bus_path_encode(void) {
38 _cleanup_free_
char *a
= NULL
, *b
= NULL
, *c
= NULL
, *d
= NULL
, *e
= NULL
, *f
= NULL
;
40 assert_se(sd_bus_path_encode("/foo/bar", "waldo", &a
) >= 0 && streq(a
, "/foo/bar/waldo"));
41 assert_se(sd_bus_path_decode(a
, "/waldo", &b
) == 0 && b
== NULL
);
42 assert_se(sd_bus_path_decode(a
, "/foo/bar", &b
) > 0 && streq(b
, "waldo"));
44 assert_se(sd_bus_path_encode("xxxx", "waldo", &c
) < 0);
45 assert_se(sd_bus_path_encode("/foo/", "waldo", &c
) < 0);
47 assert_se(sd_bus_path_encode("/foo/bar", "", &c
) >= 0 && streq(c
, "/foo/bar/_"));
48 assert_se(sd_bus_path_decode(c
, "/foo/bar", &d
) > 0 && streq(d
, ""));
50 assert_se(sd_bus_path_encode("/foo/bar", "foo.bar", &e
) >= 0 && streq(e
, "/foo/bar/foo_2ebar"));
51 assert_se(sd_bus_path_decode(e
, "/foo/bar", &f
) > 0 && streq(f
, "foo.bar"));
54 static void test_bus_path_encode_many(void) {
55 _cleanup_free_
char *a
= NULL
, *b
= NULL
, *c
= NULL
, *d
= NULL
, *e
= NULL
, *f
= NULL
;
57 assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%", NULL
) == 0);
58 assert_se(sd_bus_path_decode_many("/prefix/bar", "/prefix/%bar", NULL
) == 1);
59 assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%/suffix", NULL
) == 0);
60 assert_se(sd_bus_path_decode_many("/prefix/foobar/suffix", "/prefix/%/suffix", &a
) == 1 && streq_ptr(a
, "foobar"));
61 assert_se(sd_bus_path_decode_many("/prefix/one_foo_two/mid/three_bar_four/suffix", "/prefix/one_%_two/mid/three_%_four/suffix", &b
, &c
) == 1 && streq_ptr(b
, "foo") && streq_ptr(c
, "bar"));
62 assert_se(sd_bus_path_decode_many("/prefix/one_foo_two/mid/three_bar_four/suffix", "/prefix/one_%_two/mid/three_%_four/suffix", NULL
, &d
) == 1 && streq_ptr(d
, "bar"));
64 assert_se(sd_bus_path_decode_many("/foo/bar", "/foo/bar/%", NULL
) == 0);
65 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar%", NULL
) == 0);
66 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/bar", NULL
) == 0);
67 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%bar", NULL
) == 0);
68 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar/suffix") == 1);
69 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%%/suffix", NULL
, NULL
) == 0); /* multiple '%' are treated verbatim */
70 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffi", NULL
) == 0);
71 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffix", &e
) == 1 && streq_ptr(e
, "bar"));
72 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/%", NULL
, NULL
) == 1);
73 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/%", NULL
, NULL
, NULL
) == 1);
74 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%/%/%", NULL
, NULL
, NULL
) == 0);
75 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%", NULL
, NULL
) == 0);
76 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/", NULL
, NULL
) == 0);
77 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/", NULL
) == 0);
78 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%", NULL
) == 0);
79 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%", NULL
) == 0);
81 assert_se(sd_bus_path_encode_many(&f
, "/prefix/one_%_two/mid/three_%_four/suffix", "foo", "bar") >= 0 && streq_ptr(f
, "/prefix/one_foo_two/mid/three_bar_four/suffix"));
84 static void test_bus_label_escape_one(const char *a
, const char *b
) {
85 _cleanup_free_
char *t
= NULL
, *x
= NULL
, *y
= NULL
;
87 assert_se(t
= bus_label_escape(a
));
88 assert_se(streq(t
, b
));
90 assert_se(x
= bus_label_unescape(t
));
91 assert_se(streq(a
, x
));
93 assert_se(y
= bus_label_unescape(b
));
94 assert_se(streq(a
, y
));
97 static void test_bus_label_escape(void) {
98 test_bus_label_escape_one("foo123bar", "foo123bar");
99 test_bus_label_escape_one("foo.bar", "foo_2ebar");
100 test_bus_label_escape_one("foo_2ebar", "foo_5f2ebar");
101 test_bus_label_escape_one("", "_");
102 test_bus_label_escape_one("_", "_5f");
103 test_bus_label_escape_one("1", "_31");
104 test_bus_label_escape_one(":1", "_3a1");
107 int main(int argc
, char *argv
[]) {
108 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
, *copy
= NULL
;
110 const char *x
, *x2
, *y
, *z
, *a
, *b
, *c
, *d
, *a_signature
;
114 _cleanup_free_
char *h
= NULL
;
115 const int32_t integer_array
[] = { -1, -2, 0, 1, 2 }, *return_array
;
117 _cleanup_free_
char *first
= NULL
, *second
= NULL
, *third
= NULL
;
118 _cleanup_fclose_
FILE *ms
= NULL
;
119 size_t first_size
= 0, second_size
= 0, third_size
= 0;
120 _cleanup_(sd_bus_unrefp
) sd_bus
*bus
= NULL
;
124 test_setup_logging(LOG_INFO
);
126 r
= sd_bus_default_user(&bus
);
128 r
= sd_bus_default_system(&bus
);
130 return log_tests_skipped("Failed to connect to bus");
132 r
= sd_bus_message_new_method_call(bus
, &m
, "foobar.waldo", "/", "foobar.waldo", "Piep");
135 r
= sd_bus_message_append(m
, "");
138 r
= sd_bus_message_append(m
, "s", "a string");
141 r
= sd_bus_message_append(m
, "s", NULL
);
144 r
= sd_bus_message_append(m
, "asg", 2, "string #1", "string #2", "sba(tt)ss");
147 r
= sd_bus_message_append(m
, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
150 r
= sd_bus_message_append(m
, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
153 r
= sd_bus_message_append(m
, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10);
156 r
= sd_bus_message_append(m
, "()");
157 assert_se(r
== -EINVAL
);
159 r
= sd_bus_message_append(m
, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
162 r
= sd_bus_message_open_container(m
, 'a', "s");
165 r
= sd_bus_message_append_basic(m
, 's', "foobar");
168 r
= sd_bus_message_append_basic(m
, 's', "waldo");
171 r
= sd_bus_message_close_container(m
);
174 r
= sd_bus_message_append_string_space(m
, 5, &s
);
178 r
= sd_bus_message_append_array(m
, 'i', integer_array
, sizeof(integer_array
));
181 r
= sd_bus_message_append_array(m
, 'u', NULL
, 0);
184 r
= sd_bus_message_append(m
, "a(stdo)", 1, "foo", 815ULL, 47.0, "/");
187 r
= sd_bus_message_seal(m
, 4711, 0);
190 bus_message_dump(m
, stdout
, BUS_MESSAGE_DUMP_WITH_HEADER
);
192 ms
= open_memstream(&first
, &first_size
);
193 bus_message_dump(m
, ms
, 0);
195 assert_se(!ferror(ms
));
197 r
= bus_message_get_blob(m
, &buffer
, &sz
);
200 h
= cescape_length(buffer
, sz
);
202 log_info("message size = %zu, contents =\n%s", sz
, h
);
205 #ifndef __SANITIZE_ADDRESS__
210 #if !defined(GLIB_VERSION_2_36)
214 g
= g_dbus_message_new_from_blob(buffer
, sz
, 0, NULL
);
215 p
= g_dbus_message_print(g
, 0);
228 dbus_error_init(&error
);
230 w
= dbus_message_demarshal(buffer
, sz
, &error
);
232 log_error("%s", error
.message
);
234 dbus_message_unref(w
);
236 dbus_error_free(&error
);
240 m
= sd_bus_message_unref(m
);
242 r
= bus_message_from_malloc(bus
, buffer
, sz
, NULL
, 0, NULL
, &m
);
245 bus_message_dump(m
, stdout
, BUS_MESSAGE_DUMP_WITH_HEADER
);
248 ms
= open_memstream(&second
, &second_size
);
249 bus_message_dump(m
, ms
, 0);
251 assert_se(!ferror(ms
));
252 assert_se(first_size
== second_size
);
253 assert_se(memcmp(first
, second
, first_size
) == 0);
255 assert_se(sd_bus_message_rewind(m
, true) >= 0);
257 r
= sd_bus_message_read(m
, "ssasg", &x
, &x2
, 2, &y
, &z
, &a_signature
);
259 assert_se(streq(x
, "a string"));
260 assert_se(streq(x2
, ""));
261 assert_se(streq(y
, "string #1"));
262 assert_se(streq(z
, "string #2"));
263 assert_se(streq(a_signature
, "sba(tt)ss"));
265 r
= sd_bus_message_read(m
, "sass", &x
, 5, &y
, &z
, &a
, &b
, &c
, &d
);
267 assert_se(streq(x
, "foobar"));
268 assert_se(streq(y
, "foo"));
269 assert_se(streq(z
, "bar"));
270 assert_se(streq(a
, "waldo"));
271 assert_se(streq(b
, "piep"));
272 assert_se(streq(c
, "pap"));
273 assert_se(streq(d
, "after"));
275 r
= sd_bus_message_read(m
, "a{yv}", 2, &u
, "s", &x
, &v
, "s", &y
);
278 assert_se(streq(x
, "foo"));
280 assert_se(streq(y
, "waldo"));
282 r
= sd_bus_message_read(m
, "y(ty)", &v
, &u64
, &u
);
285 assert_se(u64
== 777);
288 r
= sd_bus_message_read(m
, "y(yt)", &v
, &u
, &u64
);
292 assert_se(u64
== 7777);
294 r
= sd_bus_message_read(m
, "y", &v
);
298 r
= sd_bus_message_read(m
, "()");
301 r
= sd_bus_message_read(m
, "ba(ss)", &boolean
, 3, &x
, &y
, &a
, &b
, &c
, &d
);
304 assert_se(streq(x
, "aaa"));
305 assert_se(streq(y
, "1"));
306 assert_se(streq(a
, "bbb"));
307 assert_se(streq(b
, "2"));
308 assert_se(streq(c
, "ccc"));
309 assert_se(streq(d
, "3"));
311 assert_se(sd_bus_message_verify_type(m
, 'a', "s") > 0);
313 r
= sd_bus_message_read(m
, "as", 2, &x
, &y
);
315 assert_se(streq(x
, "foobar"));
316 assert_se(streq(y
, "waldo"));
318 r
= sd_bus_message_read_basic(m
, 's', &s
);
320 assert_se(streq(s
, "hallo"));
322 r
= sd_bus_message_read_array(m
, 'i', (const void**) &return_array
, &sz
);
324 assert_se(sz
== sizeof(integer_array
));
325 assert_se(memcmp(integer_array
, return_array
, sz
) == 0);
327 r
= sd_bus_message_read_array(m
, 'u', (const void**) &return_array
, &sz
);
331 r
= sd_bus_message_read(m
, "a(stdo)", 1, &x
, &u64
, &dbl
, &y
);
333 assert_se(streq(x
, "foo"));
334 assert_se(u64
== 815ULL);
335 assert_se(fabs(dbl
- 47.0) < 0.1);
336 assert_se(streq(y
, "/"));
338 r
= sd_bus_message_peek_type(m
, NULL
, NULL
);
341 r
= sd_bus_message_new_method_call(bus
, ©
, "foobar.waldo", "/", "foobar.waldo", "Piep");
344 r
= sd_bus_message_rewind(m
, true);
347 r
= sd_bus_message_copy(copy
, m
, true);
350 r
= sd_bus_message_seal(copy
, 4712, 0);
354 ms
= open_memstream(&third
, &third_size
);
355 bus_message_dump(copy
, ms
, 0);
357 assert_se(!ferror(ms
));
359 printf("<%.*s>\n", (int) first_size
, first
);
360 printf("<%.*s>\n", (int) third_size
, third
);
362 assert_se(first_size
== third_size
);
363 assert_se(memcmp(first
, third
, third_size
) == 0);
365 r
= sd_bus_message_rewind(m
, true);
368 assert_se(sd_bus_message_verify_type(m
, 's', NULL
) > 0);
370 r
= sd_bus_message_skip(m
, "ssasg");
373 assert_se(sd_bus_message_verify_type(m
, 's', NULL
) > 0);
375 r
= sd_bus_message_skip(m
, "sass");
378 assert_se(sd_bus_message_verify_type(m
, 'a', "{yv}") > 0);
380 r
= sd_bus_message_skip(m
, "a{yv}y(ty)y(yt)y");
383 assert_se(sd_bus_message_verify_type(m
, 'b', NULL
) > 0);
385 r
= sd_bus_message_read(m
, "b", &boolean
);
389 r
= sd_bus_message_enter_container(m
, 0, NULL
);
392 r
= sd_bus_message_read(m
, "(ss)", &x
, &y
);
395 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
398 r
= sd_bus_message_read(m
, "(ss)", &c
, &d
);
401 r
= sd_bus_message_read(m
, "(ss)", &x
, &y
);
404 r
= sd_bus_message_exit_container(m
);
407 assert_se(streq(x
, "aaa"));
408 assert_se(streq(y
, "1"));
409 assert_se(streq(a
, "bbb"));
410 assert_se(streq(b
, "2"));
411 assert_se(streq(c
, "ccc"));
412 assert_se(streq(d
, "3"));
414 test_bus_label_escape();
415 test_bus_path_encode();
416 test_bus_path_encode_unique();
417 test_bus_path_encode_many();