2 This file is part of systemd.
4 Copyright 2013 Lennart Poettering
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
28 #include <dbus/dbus.h>
33 #include "alloc-util.h"
35 #include "bus-label.h"
36 #include "bus-message.h"
39 #include "hexdecoct.h"
43 static void test_bus_path_encode_unique(void) {
44 _cleanup_free_
char *a
= NULL
, *b
= NULL
, *c
= NULL
, *d
= NULL
, *e
= NULL
;
46 assert_se(bus_path_encode_unique(NULL
, "/foo/bar", "some.sender", "a.suffix", &a
) >= 0 && streq_ptr(a
, "/foo/bar/some_2esender/a_2esuffix"));
47 assert_se(bus_path_decode_unique(a
, "/foo/bar", &b
, &c
) > 0 && streq_ptr(b
, "some.sender") && streq_ptr(c
, "a.suffix"));
48 assert_se(bus_path_decode_unique(a
, "/bar/foo", &d
, &d
) == 0 && !d
);
49 assert_se(bus_path_decode_unique("/foo/bar/onlyOneSuffix", "/foo/bar", &d
, &d
) == 0 && !d
);
50 assert_se(bus_path_decode_unique("/foo/bar/_/_", "/foo/bar", &d
, &e
) > 0 && streq_ptr(d
, "") && streq_ptr(e
, ""));
53 static void test_bus_path_encode(void) {
54 _cleanup_free_
char *a
= NULL
, *b
= NULL
, *c
= NULL
, *d
= NULL
, *e
= NULL
, *f
= NULL
;
56 assert_se(sd_bus_path_encode("/foo/bar", "waldo", &a
) >= 0 && streq(a
, "/foo/bar/waldo"));
57 assert_se(sd_bus_path_decode(a
, "/waldo", &b
) == 0 && b
== NULL
);
58 assert_se(sd_bus_path_decode(a
, "/foo/bar", &b
) > 0 && streq(b
, "waldo"));
60 assert_se(sd_bus_path_encode("xxxx", "waldo", &c
) < 0);
61 assert_se(sd_bus_path_encode("/foo/", "waldo", &c
) < 0);
63 assert_se(sd_bus_path_encode("/foo/bar", "", &c
) >= 0 && streq(c
, "/foo/bar/_"));
64 assert_se(sd_bus_path_decode(c
, "/foo/bar", &d
) > 0 && streq(d
, ""));
66 assert_se(sd_bus_path_encode("/foo/bar", "foo.bar", &e
) >= 0 && streq(e
, "/foo/bar/foo_2ebar"));
67 assert_se(sd_bus_path_decode(e
, "/foo/bar", &f
) > 0 && streq(f
, "foo.bar"));
70 static void test_bus_path_encode_many(void) {
71 _cleanup_free_
char *a
= NULL
, *b
= NULL
, *c
= NULL
, *d
= NULL
, *e
= NULL
, *f
= NULL
;
73 assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%", NULL
) == 0);
74 assert_se(sd_bus_path_decode_many("/prefix/bar", "/prefix/%bar", NULL
) == 1);
75 assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%/suffix", NULL
) == 0);
76 assert_se(sd_bus_path_decode_many("/prefix/foobar/suffix", "/prefix/%/suffix", &a
) == 1 && streq_ptr(a
, "foobar"));
77 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"));
78 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"));
80 assert_se(sd_bus_path_decode_many("/foo/bar", "/foo/bar/%", NULL
) == 0);
81 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar%", NULL
) == 0);
82 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/bar", NULL
) == 0);
83 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%bar", NULL
) == 0);
84 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/bar/suffix") == 1);
85 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%%/suffix", NULL
, NULL
) == 0); /* multiple '%' are treated verbatim */
86 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffi", NULL
) == 0);
87 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffix", &e
) == 1 && streq_ptr(e
, "bar"));
88 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/%", NULL
, NULL
) == 1);
89 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/%", NULL
, NULL
, NULL
) == 1);
90 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%/%/%", NULL
, NULL
, NULL
) == 0);
91 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%", NULL
, NULL
) == 0);
92 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/", NULL
, NULL
) == 0);
93 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/", NULL
) == 0);
94 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%", NULL
) == 0);
95 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%", NULL
) == 0);
97 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"));
100 static void test_bus_label_escape_one(const char *a
, const char *b
) {
101 _cleanup_free_
char *t
= NULL
, *x
= NULL
, *y
= NULL
;
103 assert_se(t
= bus_label_escape(a
));
104 assert_se(streq(t
, b
));
106 assert_se(x
= bus_label_unescape(t
));
107 assert_se(streq(a
, x
));
109 assert_se(y
= bus_label_unescape(b
));
110 assert_se(streq(a
, y
));
113 static void test_bus_label_escape(void) {
114 test_bus_label_escape_one("foo123bar", "foo123bar");
115 test_bus_label_escape_one("foo.bar", "foo_2ebar");
116 test_bus_label_escape_one("foo_2ebar", "foo_5f2ebar");
117 test_bus_label_escape_one("", "_");
118 test_bus_label_escape_one("_", "_5f");
119 test_bus_label_escape_one("1", "_31");
120 test_bus_label_escape_one(":1", "_3a1");
123 int main(int argc
, char *argv
[]) {
124 _cleanup_(sd_bus_message_unrefp
) sd_bus_message
*m
= NULL
, *copy
= NULL
;
126 const char *x
, *x2
, *y
, *z
, *a
, *b
, *c
, *d
, *a_signature
;
131 const int32_t integer_array
[] = { -1, -2, 0, 1, 2 }, *return_array
;
133 _cleanup_free_
char *first
= NULL
, *second
= NULL
, *third
= NULL
;
134 _cleanup_fclose_
FILE *ms
= NULL
;
135 size_t first_size
= 0, second_size
= 0, third_size
= 0;
136 _cleanup_(sd_bus_unrefp
) sd_bus
*bus
= NULL
;
140 r
= sd_bus_default_user(&bus
);
142 return EXIT_TEST_SKIP
;
144 r
= sd_bus_message_new_method_call(bus
, &m
, "foobar.waldo", "/", "foobar.waldo", "Piep");
147 r
= sd_bus_message_append(m
, "");
150 r
= sd_bus_message_append(m
, "s", "a string");
153 r
= sd_bus_message_append(m
, "s", NULL
);
156 r
= sd_bus_message_append(m
, "asg", 2, "string #1", "string #2", "sba(tt)ss");
159 r
= sd_bus_message_append(m
, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
162 r
= sd_bus_message_append(m
, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
165 r
= sd_bus_message_append(m
, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10);
168 r
= sd_bus_message_append(m
, "()");
171 r
= sd_bus_message_append(m
, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
174 r
= sd_bus_message_open_container(m
, 'a', "s");
177 r
= sd_bus_message_append_basic(m
, 's', "foobar");
180 r
= sd_bus_message_append_basic(m
, 's', "waldo");
183 r
= sd_bus_message_close_container(m
);
186 r
= sd_bus_message_append_string_space(m
, 5, &s
);
190 r
= sd_bus_message_append_array(m
, 'i', integer_array
, sizeof(integer_array
));
193 r
= sd_bus_message_append_array(m
, 'u', NULL
, 0);
196 r
= sd_bus_message_append(m
, "a(stdo)", 1, "foo", 815ULL, 47.0, "/");
199 r
= bus_message_seal(m
, 4711, 0);
202 bus_message_dump(m
, stdout
, BUS_MESSAGE_DUMP_WITH_HEADER
);
204 ms
= open_memstream(&first
, &first_size
);
205 bus_message_dump(m
, ms
, 0);
207 assert_se(!ferror(ms
));
209 r
= bus_message_get_blob(m
, &buffer
, &sz
);
212 h
= hexmem(buffer
, sz
);
215 log_info("message size = %zu, contents =\n%s", sz
, h
);
223 #if !defined(GLIB_VERSION_2_36)
227 g
= g_dbus_message_new_from_blob(buffer
, sz
, 0, NULL
);
228 p
= g_dbus_message_print(g
, 0);
240 dbus_error_init(&error
);
242 w
= dbus_message_demarshal(buffer
, sz
, &error
);
244 log_error("%s", error
.message
);
246 dbus_message_unref(w
);
248 dbus_error_free(&error
);
252 m
= sd_bus_message_unref(m
);
254 r
= bus_message_from_malloc(bus
, buffer
, sz
, NULL
, 0, NULL
, &m
);
257 bus_message_dump(m
, stdout
, BUS_MESSAGE_DUMP_WITH_HEADER
);
260 ms
= open_memstream(&second
, &second_size
);
261 bus_message_dump(m
, ms
, 0);
263 assert_se(!ferror(ms
));
264 assert_se(first_size
== second_size
);
265 assert_se(memcmp(first
, second
, first_size
) == 0);
267 assert_se(sd_bus_message_rewind(m
, true) >= 0);
269 r
= sd_bus_message_read(m
, "ssasg", &x
, &x2
, 2, &y
, &z
, &a_signature
);
271 assert_se(streq(x
, "a string"));
272 assert_se(streq(x2
, ""));
273 assert_se(streq(y
, "string #1"));
274 assert_se(streq(z
, "string #2"));
275 assert_se(streq(a_signature
, "sba(tt)ss"));
277 r
= sd_bus_message_read(m
, "sass", &x
, 5, &y
, &z
, &a
, &b
, &c
, &d
);
279 assert_se(streq(x
, "foobar"));
280 assert_se(streq(y
, "foo"));
281 assert_se(streq(z
, "bar"));
282 assert_se(streq(a
, "waldo"));
283 assert_se(streq(b
, "piep"));
284 assert_se(streq(c
, "pap"));
285 assert_se(streq(d
, "after"));
287 r
= sd_bus_message_read(m
, "a{yv}", 2, &u
, "s", &x
, &v
, "s", &y
);
290 assert_se(streq(x
, "foo"));
292 assert_se(streq(y
, "waldo"));
294 r
= sd_bus_message_read(m
, "y(ty)", &v
, &u64
, &u
);
297 assert_se(u64
== 777);
300 r
= sd_bus_message_read(m
, "y(yt)", &v
, &u
, &u64
);
304 assert_se(u64
== 7777);
306 r
= sd_bus_message_read(m
, "y", &v
);
310 r
= sd_bus_message_read(m
, "()");
313 r
= sd_bus_message_read(m
, "ba(ss)", &boolean
, 3, &x
, &y
, &a
, &b
, &c
, &d
);
316 assert_se(streq(x
, "aaa"));
317 assert_se(streq(y
, "1"));
318 assert_se(streq(a
, "bbb"));
319 assert_se(streq(b
, "2"));
320 assert_se(streq(c
, "ccc"));
321 assert_se(streq(d
, "3"));
323 assert_se(sd_bus_message_verify_type(m
, 'a', "s") > 0);
325 r
= sd_bus_message_read(m
, "as", 2, &x
, &y
);
327 assert_se(streq(x
, "foobar"));
328 assert_se(streq(y
, "waldo"));
330 r
= sd_bus_message_read_basic(m
, 's', &s
);
332 assert_se(streq(s
, "hallo"));
334 r
= sd_bus_message_read_array(m
, 'i', (const void**) &return_array
, &sz
);
336 assert_se(sz
== sizeof(integer_array
));
337 assert_se(memcmp(integer_array
, return_array
, sz
) == 0);
339 r
= sd_bus_message_read_array(m
, 'u', (const void**) &return_array
, &sz
);
343 r
= sd_bus_message_read(m
, "a(stdo)", 1, &x
, &u64
, &dbl
, &y
);
345 assert_se(streq(x
, "foo"));
346 assert_se(u64
== 815ULL);
347 assert_se(fabs(dbl
- 47.0) < 0.1);
348 assert_se(streq(y
, "/"));
350 r
= sd_bus_message_peek_type(m
, NULL
, NULL
);
353 r
= sd_bus_message_new_method_call(bus
, ©
, "foobar.waldo", "/", "foobar.waldo", "Piep");
356 r
= sd_bus_message_rewind(m
, true);
359 r
= sd_bus_message_copy(copy
, m
, true);
362 r
= bus_message_seal(copy
, 4712, 0);
366 ms
= open_memstream(&third
, &third_size
);
367 bus_message_dump(copy
, ms
, 0);
369 assert_se(!ferror(ms
));
371 printf("<%.*s>\n", (int) first_size
, first
);
372 printf("<%.*s>\n", (int) third_size
, third
);
374 assert_se(first_size
== third_size
);
375 assert_se(memcmp(first
, third
, third_size
) == 0);
377 r
= sd_bus_message_rewind(m
, true);
380 assert_se(sd_bus_message_verify_type(m
, 's', NULL
) > 0);
382 r
= sd_bus_message_skip(m
, "ssasg");
385 assert_se(sd_bus_message_verify_type(m
, 's', NULL
) > 0);
387 r
= sd_bus_message_skip(m
, "sass");
390 assert_se(sd_bus_message_verify_type(m
, 'a', "{yv}") > 0);
392 r
= sd_bus_message_skip(m
, "a{yv}y(ty)y(yt)y()");
395 assert_se(sd_bus_message_verify_type(m
, 'b', NULL
) > 0);
397 r
= sd_bus_message_read(m
, "b", &boolean
);
401 r
= sd_bus_message_enter_container(m
, 0, NULL
);
404 r
= sd_bus_message_read(m
, "(ss)", &x
, &y
);
407 r
= sd_bus_message_read(m
, "(ss)", &a
, &b
);
410 r
= sd_bus_message_read(m
, "(ss)", &c
, &d
);
413 r
= sd_bus_message_read(m
, "(ss)", &x
, &y
);
416 r
= sd_bus_message_exit_container(m
);
419 assert_se(streq(x
, "aaa"));
420 assert_se(streq(y
, "1"));
421 assert_se(streq(a
, "bbb"));
422 assert_se(streq(b
, "2"));
423 assert_se(streq(c
, "ccc"));
424 assert_se(streq(d
, "3"));
426 test_bus_label_escape();
427 test_bus_path_encode();
428 test_bus_path_encode_unique();
429 test_bus_path_encode_many();