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"
28 static void test_bus_path_encode_unique(void) {
29 _cleanup_free_
char *a
= NULL
, *b
= NULL
, *c
= NULL
, *d
= NULL
, *e
= NULL
;
31 assert_se(bus_path_encode_unique(NULL
, "/foo/bar", "some.sender", "a.suffix", &a
) >= 0 && streq_ptr(a
, "/foo/bar/some_2esender/a_2esuffix"));
32 assert_se(bus_path_decode_unique(a
, "/foo/bar", &b
, &c
) > 0 && streq_ptr(b
, "some.sender") && streq_ptr(c
, "a.suffix"));
33 assert_se(bus_path_decode_unique(a
, "/bar/foo", &d
, &d
) == 0 && !d
);
34 assert_se(bus_path_decode_unique("/foo/bar/onlyOneSuffix", "/foo/bar", &d
, &d
) == 0 && !d
);
35 assert_se(bus_path_decode_unique("/foo/bar/_/_", "/foo/bar", &d
, &e
) > 0 && streq_ptr(d
, "") && streq_ptr(e
, ""));
38 static void test_bus_path_encode(void) {
39 _cleanup_free_
char *a
= NULL
, *b
= NULL
, *c
= NULL
, *d
= NULL
, *e
= NULL
, *f
= NULL
;
41 assert_se(sd_bus_path_encode("/foo/bar", "waldo", &a
) >= 0 && streq(a
, "/foo/bar/waldo"));
42 assert_se(sd_bus_path_decode(a
, "/waldo", &b
) == 0 && b
== NULL
);
43 assert_se(sd_bus_path_decode(a
, "/foo/bar", &b
) > 0 && streq(b
, "waldo"));
45 assert_se(sd_bus_path_encode("xxxx", "waldo", &c
) < 0);
46 assert_se(sd_bus_path_encode("/foo/", "waldo", &c
) < 0);
48 assert_se(sd_bus_path_encode("/foo/bar", "", &c
) >= 0 && streq(c
, "/foo/bar/_"));
49 assert_se(sd_bus_path_decode(c
, "/foo/bar", &d
) > 0 && streq(d
, ""));
51 assert_se(sd_bus_path_encode("/foo/bar", "foo.bar", &e
) >= 0 && streq(e
, "/foo/bar/foo_2ebar"));
52 assert_se(sd_bus_path_decode(e
, "/foo/bar", &f
) > 0 && streq(f
, "foo.bar"));
55 static void test_bus_path_encode_many(void) {
56 _cleanup_free_
char *a
= NULL
, *b
= NULL
, *c
= NULL
, *d
= NULL
, *e
= NULL
, *f
= NULL
;
58 assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%", NULL
) == 0);
59 assert_se(sd_bus_path_decode_many("/prefix/bar", "/prefix/%bar", NULL
) == 1);
60 assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%/suffix", NULL
) == 0);
61 assert_se(sd_bus_path_decode_many("/prefix/foobar/suffix", "/prefix/%/suffix", &a
) == 1 && streq_ptr(a
, "foobar"));
62 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"));
63 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"));
65 assert_se(sd_bus_path_decode_many("/foo/bar", "/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", NULL
) == 0);
69 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar/suffix") == 1);
70 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%%/suffix", NULL
, NULL
) == 0); /* multiple '%' are treated verbatim */
71 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffi", NULL
) == 0);
72 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffix", &e
) == 1 && streq_ptr(e
, "bar"));
73 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/%", NULL
, NULL
) == 1);
74 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/%", NULL
, NULL
, NULL
) == 1);
75 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%/%/%", NULL
, 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
, 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);
80 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%", NULL
) == 0);
82 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"));
85 static void test_bus_label_escape_one(const char *a
, const char *b
) {
86 _cleanup_free_
char *t
= NULL
, *x
= NULL
, *y
= NULL
;
88 assert_se(t
= bus_label_escape(a
));
89 assert_se(streq(t
, b
));
91 assert_se(x
= bus_label_unescape(t
));
92 assert_se(streq(a
, x
));
94 assert_se(y
= bus_label_unescape(b
));
95 assert_se(streq(a
, y
));
98 static void test_bus_label_escape(void) {
99 test_bus_label_escape_one("foo123bar", "foo123bar");
100 test_bus_label_escape_one("foo.bar", "foo_2ebar");
101 test_bus_label_escape_one("foo_2ebar", "foo_5f2ebar");
102 test_bus_label_escape_one("", "_");
103 test_bus_label_escape_one("_", "_5f");
104 test_bus_label_escape_one("1", "_31");
105 test_bus_label_escape_one(":1", "_3a1");
108 int main(int argc
, char *argv
[]) {
109 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
, *copy
= NULL
;
111 const char *x
, *x2
, *y
, *z
, *a
, *b
, *c
, *d
, *a_signature
;
115 _cleanup_free_
char *h
= NULL
;
116 const int32_t integer_array
[] = { -1, -2, 0, 1, 2 }, *return_array
;
118 _cleanup_free_
char *first
= NULL
, *second
= NULL
, *third
= NULL
;
119 _cleanup_fclose_
FILE *ms
= NULL
;
120 size_t first_size
= 0, second_size
= 0, third_size
= 0;
121 _cleanup_(sd_bus_unrefp
) sd_bus
*bus
= NULL
;
125 test_setup_logging(LOG_INFO
);
127 r
= sd_bus_default_user(&bus
);
129 r
= sd_bus_default_system(&bus
);
131 return log_tests_skipped("Failed to connect to bus");
133 r
= sd_bus_message_new_method_call(bus
, &m
, "foobar.waldo", "/", "foobar.waldo", "Piep");
136 r
= sd_bus_message_append(m
, "");
139 r
= sd_bus_message_append(m
, "s", "a string");
142 r
= sd_bus_message_append(m
, "s", NULL
);
145 r
= sd_bus_message_append(m
, "asg", 2, "string #1", "string #2", "sba(tt)ss");
148 r
= sd_bus_message_append(m
, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
151 r
= sd_bus_message_append(m
, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
154 r
= sd_bus_message_append(m
, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10);
157 r
= sd_bus_message_append(m
, "()");
158 assert_se(r
== -EINVAL
);
160 r
= sd_bus_message_append(m
, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
163 r
= sd_bus_message_open_container(m
, 'a', "s");
166 r
= sd_bus_message_append_basic(m
, 's', "foobar");
169 r
= sd_bus_message_append_basic(m
, 's', "waldo");
172 r
= sd_bus_message_close_container(m
);
175 r
= sd_bus_message_append_string_space(m
, 5, &s
);
179 r
= sd_bus_message_append_array(m
, 'i', integer_array
, sizeof(integer_array
));
182 r
= sd_bus_message_append_array(m
, 'u', NULL
, 0);
185 r
= sd_bus_message_append(m
, "a(stdo)", 1, "foo", 815ULL, 47.0, "/");
188 r
= sd_bus_message_seal(m
, 4711, 0);
191 bus_message_dump(m
, stdout
, BUS_MESSAGE_DUMP_WITH_HEADER
);
193 ms
= open_memstream_unlocked(&first
, &first_size
);
194 bus_message_dump(m
, ms
, 0);
196 assert_se(!ferror(ms
));
198 r
= bus_message_get_blob(m
, &buffer
, &sz
);
201 h
= cescape_length(buffer
, sz
);
203 log_info("message size = %zu, contents =\n%s", sz
, h
);
206 /* Work-around for asan bug. See c8d980a3e962aba2ea3a4cedf75fa94890a6d746. */
207 #if !HAS_FEATURE_ADDRESS_SANITIZER
212 #if !defined(GLIB_VERSION_2_36)
216 g
= g_dbus_message_new_from_blob(buffer
, sz
, 0, NULL
);
217 p
= g_dbus_message_print(g
, 0);
230 dbus_error_init(&error
);
232 w
= dbus_message_demarshal(buffer
, sz
, &error
);
234 log_error("%s", error
.message
);
236 dbus_message_unref(w
);
238 dbus_error_free(&error
);
242 m
= sd_bus_message_unref(m
);
244 r
= bus_message_from_malloc(bus
, buffer
, sz
, NULL
, 0, NULL
, &m
);
247 bus_message_dump(m
, stdout
, BUS_MESSAGE_DUMP_WITH_HEADER
);
250 ms
= open_memstream_unlocked(&second
, &second_size
);
251 bus_message_dump(m
, ms
, 0);
253 assert_se(!ferror(ms
));
254 assert_se(first_size
== second_size
);
255 assert_se(memcmp(first
, second
, first_size
) == 0);
257 assert_se(sd_bus_message_rewind(m
, true) >= 0);
259 r
= sd_bus_message_read(m
, "ssasg", &x
, &x2
, 2, &y
, &z
, &a_signature
);
261 assert_se(streq(x
, "a string"));
262 assert_se(streq(x2
, ""));
263 assert_se(streq(y
, "string #1"));
264 assert_se(streq(z
, "string #2"));
265 assert_se(streq(a_signature
, "sba(tt)ss"));
267 r
= sd_bus_message_read(m
, "sass", &x
, 5, &y
, &z
, &a
, &b
, &c
, &d
);
269 assert_se(streq(x
, "foobar"));
270 assert_se(streq(y
, "foo"));
271 assert_se(streq(z
, "bar"));
272 assert_se(streq(a
, "waldo"));
273 assert_se(streq(b
, "piep"));
274 assert_se(streq(c
, "pap"));
275 assert_se(streq(d
, "after"));
277 r
= sd_bus_message_read(m
, "a{yv}", 2, &u
, "s", &x
, &v
, "s", &y
);
280 assert_se(streq(x
, "foo"));
282 assert_se(streq(y
, "waldo"));
284 r
= sd_bus_message_read(m
, "y(ty)", &v
, &u64
, &u
);
287 assert_se(u64
== 777);
290 r
= sd_bus_message_read(m
, "y(yt)", &v
, &u
, &u64
);
294 assert_se(u64
== 7777);
296 r
= sd_bus_message_read(m
, "y", &v
);
300 r
= sd_bus_message_read(m
, "()");
303 r
= sd_bus_message_read(m
, "ba(ss)", &boolean
, 3, &x
, &y
, &a
, &b
, &c
, &d
);
306 assert_se(streq(x
, "aaa"));
307 assert_se(streq(y
, "1"));
308 assert_se(streq(a
, "bbb"));
309 assert_se(streq(b
, "2"));
310 assert_se(streq(c
, "ccc"));
311 assert_se(streq(d
, "3"));
313 assert_se(sd_bus_message_verify_type(m
, 'a', "s") > 0);
315 r
= sd_bus_message_read(m
, "as", 2, &x
, &y
);
317 assert_se(streq(x
, "foobar"));
318 assert_se(streq(y
, "waldo"));
320 r
= sd_bus_message_read_basic(m
, 's', &s
);
322 assert_se(streq(s
, "hallo"));
324 r
= sd_bus_message_read_array(m
, 'i', (const void**) &return_array
, &sz
);
326 assert_se(sz
== sizeof(integer_array
));
327 assert_se(memcmp(integer_array
, return_array
, sz
) == 0);
329 r
= sd_bus_message_read_array(m
, 'u', (const void**) &return_array
, &sz
);
333 r
= sd_bus_message_read(m
, "a(stdo)", 1, &x
, &u64
, &dbl
, &y
);
335 assert_se(streq(x
, "foo"));
336 assert_se(u64
== 815ULL);
337 assert_se(fabs(dbl
- 47.0) < 0.1);
338 assert_se(streq(y
, "/"));
340 r
= sd_bus_message_peek_type(m
, NULL
, NULL
);
343 r
= sd_bus_message_new_method_call(bus
, ©
, "foobar.waldo", "/", "foobar.waldo", "Piep");
346 r
= sd_bus_message_rewind(m
, true);
349 r
= sd_bus_message_copy(copy
, m
, true);
352 r
= sd_bus_message_seal(copy
, 4712, 0);
356 ms
= open_memstream_unlocked(&third
, &third_size
);
357 bus_message_dump(copy
, ms
, 0);
359 assert_se(!ferror(ms
));
361 printf("<%.*s>\n", (int) first_size
, first
);
362 printf("<%.*s>\n", (int) third_size
, third
);
364 assert_se(first_size
== third_size
);
365 assert_se(memcmp(first
, third
, third_size
) == 0);
367 r
= sd_bus_message_rewind(m
, true);
370 assert_se(sd_bus_message_verify_type(m
, 's', NULL
) > 0);
372 r
= sd_bus_message_skip(m
, "ssasg");
375 assert_se(sd_bus_message_verify_type(m
, 's', NULL
) > 0);
377 r
= sd_bus_message_skip(m
, "sass");
380 assert_se(sd_bus_message_verify_type(m
, 'a', "{yv}") > 0);
382 r
= sd_bus_message_skip(m
, "a{yv}y(ty)y(yt)y");
385 assert_se(sd_bus_message_verify_type(m
, 'b', NULL
) > 0);
387 r
= sd_bus_message_read(m
, "b", &boolean
);
391 r
= sd_bus_message_enter_container(m
, 0, NULL
);
394 r
= sd_bus_message_read(m
, "(ss)", &x
, &y
);
397 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
400 r
= sd_bus_message_read(m
, "(ss)", &c
, &d
);
403 r
= sd_bus_message_read(m
, "(ss)", &x
, &y
);
406 r
= sd_bus_message_exit_container(m
);
409 assert_se(streq(x
, "aaa"));
410 assert_se(streq(y
, "1"));
411 assert_se(streq(a
, "bbb"));
412 assert_se(streq(b
, "2"));
413 assert_se(streq(c
, "ccc"));
414 assert_se(streq(d
, "3"));
416 test_bus_label_escape();
417 test_bus_path_encode();
418 test_bus_path_encode_unique();
419 test_bus_path_encode_many();