]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/libsystemd/sd-bus/test-bus-marshal.c
Merge pull request #1659 from vcaputo/journal_verify_envalid
[thirdparty/systemd.git] / src / libsystemd / sd-bus / test-bus-marshal.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4 This file is part of systemd.
5
6 Copyright 2013 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <stdlib.h>
23 #include <math.h>
24
25 #ifdef HAVE_GLIB
26 #include <gio/gio.h>
27 #endif
28
29 #ifdef HAVE_DBUS
30 #include <dbus/dbus.h>
31 #endif
32
33 #include "log.h"
34 #include "util.h"
35
36 #include "sd-bus.h"
37 #include "bus-message.h"
38 #include "bus-util.h"
39 #include "bus-dump.h"
40 #include "bus-label.h"
41
42 static void test_bus_path_encode_unique(void) {
43 _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL;
44
45 assert_se(bus_path_encode_unique(NULL, "/foo/bar", "some.sender", "a.suffix", &a) >= 0 && streq_ptr(a, "/foo/bar/some_2esender/a_2esuffix"));
46 assert_se(bus_path_decode_unique(a, "/foo/bar", &b, &c) > 0 && streq_ptr(b, "some.sender") && streq_ptr(c, "a.suffix"));
47 assert_se(bus_path_decode_unique(a, "/bar/foo", &d, &d) == 0 && !d);
48 assert_se(bus_path_decode_unique("/foo/bar/onlyOneSuffix", "/foo/bar", &d, &d) == 0 && !d);
49 assert_se(bus_path_decode_unique("/foo/bar/_/_", "/foo/bar", &d, &e) > 0 && streq_ptr(d, "") && streq_ptr(e, ""));
50 }
51
52 static void test_bus_path_encode(void) {
53 _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
54
55 assert_se(sd_bus_path_encode("/foo/bar", "waldo", &a) >= 0 && streq(a, "/foo/bar/waldo"));
56 assert_se(sd_bus_path_decode(a, "/waldo", &b) == 0 && b == NULL);
57 assert_se(sd_bus_path_decode(a, "/foo/bar", &b) > 0 && streq(b, "waldo"));
58
59 assert_se(sd_bus_path_encode("xxxx", "waldo", &c) < 0);
60 assert_se(sd_bus_path_encode("/foo/", "waldo", &c) < 0);
61
62 assert_se(sd_bus_path_encode("/foo/bar", "", &c) >= 0 && streq(c, "/foo/bar/_"));
63 assert_se(sd_bus_path_decode(c, "/foo/bar", &d) > 0 && streq(d, ""));
64
65 assert_se(sd_bus_path_encode("/foo/bar", "foo.bar", &e) >= 0 && streq(e, "/foo/bar/foo_2ebar"));
66 assert_se(sd_bus_path_decode(e, "/foo/bar", &f) > 0 && streq(f, "foo.bar"));
67 }
68
69 static void test_bus_path_encode_many(void) {
70 _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL, *d = NULL, *e = NULL, *f = NULL;
71
72 assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%", NULL) == 0);
73 assert_se(sd_bus_path_decode_many("/prefix/bar", "/prefix/%bar", NULL) == 1);
74 assert_se(sd_bus_path_decode_many("/foo/bar", "/prefix/%/suffix", NULL) == 0);
75 assert_se(sd_bus_path_decode_many("/prefix/foobar/suffix", "/prefix/%/suffix", &a) == 1 && streq_ptr(a, "foobar"));
76 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"));
77 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"));
78
79 assert_se(sd_bus_path_decode_many("/foo/bar", "/foo/bar/%", NULL) == 0);
80 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/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/suffix") == 1);
84 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%%/suffix", NULL, NULL) == 0); /* multiple '%' are treated verbatim */
85 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffi", NULL) == 0);
86 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/suffix", &e) == 1 && streq_ptr(e, "bar"));
87 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/foo/%/%", NULL, NULL) == 1);
88 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%/%", NULL, NULL, NULL) == 1);
89 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "%/%/%", NULL, NULL, NULL) == 0);
90 assert_se(sd_bus_path_decode_many("/foo/bar/suffix", "/%/%", 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) == 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
96 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"));
97 }
98
99 static void test_bus_label_escape_one(const char *a, const char *b) {
100 _cleanup_free_ char *t = NULL, *x = NULL, *y = NULL;
101
102 assert_se(t = bus_label_escape(a));
103 assert_se(streq(t, b));
104
105 assert_se(x = bus_label_unescape(t));
106 assert_se(streq(a, x));
107
108 assert_se(y = bus_label_unescape(b));
109 assert_se(streq(a, y));
110 }
111
112 static void test_bus_label_escape(void) {
113 test_bus_label_escape_one("foo123bar", "foo123bar");
114 test_bus_label_escape_one("foo.bar", "foo_2ebar");
115 test_bus_label_escape_one("foo_2ebar", "foo_5f2ebar");
116 test_bus_label_escape_one("", "_");
117 test_bus_label_escape_one("_", "_5f");
118 test_bus_label_escape_one("1", "_31");
119 test_bus_label_escape_one(":1", "_3a1");
120 }
121
122 int main(int argc, char *argv[]) {
123 _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *copy = NULL;
124 int r, boolean;
125 const char *x, *x2, *y, *z, *a, *b, *c, *d, *a_signature;
126 uint8_t u, v;
127 void *buffer = NULL;
128 size_t sz;
129 char *h;
130 const int32_t integer_array[] = { -1, -2, 0, 1, 2 }, *return_array;
131 char *s;
132 _cleanup_free_ char *first = NULL, *second = NULL, *third = NULL;
133 _cleanup_fclose_ FILE *ms = NULL;
134 size_t first_size = 0, second_size = 0, third_size = 0;
135 _cleanup_bus_unref_ sd_bus *bus = NULL;
136 double dbl;
137 uint64_t u64;
138
139 r = sd_bus_default_system(&bus);
140 if (r < 0)
141 return EXIT_TEST_SKIP;
142
143 r = sd_bus_message_new_method_call(bus, &m, "foobar.waldo", "/", "foobar.waldo", "Piep");
144 assert_se(r >= 0);
145
146 r = sd_bus_message_append(m, "");
147 assert_se(r >= 0);
148
149 r = sd_bus_message_append(m, "s", "a string");
150 assert_se(r >= 0);
151
152 r = sd_bus_message_append(m, "s", NULL);
153 assert_se(r >= 0);
154
155 r = sd_bus_message_append(m, "asg", 2, "string #1", "string #2", "sba(tt)ss");
156 assert_se(r >= 0);
157
158 r = sd_bus_message_append(m, "sass", "foobar", 5, "foo", "bar", "waldo", "piep", "pap", "after");
159 assert_se(r >= 0);
160
161 r = sd_bus_message_append(m, "a{yv}", 2, 3, "s", "foo", 5, "s", "waldo");
162 assert_se(r >= 0);
163
164 r = sd_bus_message_append(m, "y(ty)y(yt)y", 8, 777ULL, 7, 9, 77, 7777ULL, 10);
165 assert_se(r >= 0);
166
167 r = sd_bus_message_append(m, "()");
168 assert_se(r >= 0);
169
170 r = sd_bus_message_append(m, "ba(ss)", 255, 3, "aaa", "1", "bbb", "2", "ccc", "3");
171 assert_se(r >= 0);
172
173 r = sd_bus_message_open_container(m, 'a', "s");
174 assert_se(r >= 0);
175
176 r = sd_bus_message_append_basic(m, 's', "foobar");
177 assert_se(r >= 0);
178
179 r = sd_bus_message_append_basic(m, 's', "waldo");
180 assert_se(r >= 0);
181
182 r = sd_bus_message_close_container(m);
183 assert_se(r >= 0);
184
185 r = sd_bus_message_append_string_space(m, 5, &s);
186 assert_se(r >= 0);
187 strcpy(s, "hallo");
188
189 r = sd_bus_message_append_array(m, 'i', integer_array, sizeof(integer_array));
190 assert_se(r >= 0);
191
192 r = sd_bus_message_append_array(m, 'u', NULL, 0);
193 assert_se(r >= 0);
194
195 r = sd_bus_message_append(m, "a(stdo)", 1, "foo", 815ULL, 47.0, "/");
196 assert_se(r >= 0);
197
198 r = bus_message_seal(m, 4711, 0);
199 assert_se(r >= 0);
200
201 bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
202
203 ms = open_memstream(&first, &first_size);
204 bus_message_dump(m, ms, 0);
205 fflush(ms);
206 assert_se(!ferror(ms));
207
208 r = bus_message_get_blob(m, &buffer, &sz);
209 assert_se(r >= 0);
210
211 h = hexmem(buffer, sz);
212 assert_se(h);
213
214 log_info("message size = %zu, contents =\n%s", sz, h);
215 free(h);
216
217 #ifdef HAVE_GLIB
218 {
219 GDBusMessage *g;
220 char *p;
221
222 #if !defined(GLIB_VERSION_2_36)
223 g_type_init();
224 #endif
225
226 g = g_dbus_message_new_from_blob(buffer, sz, 0, NULL);
227 p = g_dbus_message_print(g, 0);
228 log_info("%s", p);
229 g_free(p);
230 g_object_unref(g);
231 }
232 #endif
233
234 #ifdef HAVE_DBUS
235 {
236 DBusMessage *w;
237 DBusError error;
238
239 dbus_error_init(&error);
240
241 w = dbus_message_demarshal(buffer, sz, &error);
242 if (!w)
243 log_error("%s", error.message);
244 else
245 dbus_message_unref(w);
246 }
247 #endif
248
249 m = sd_bus_message_unref(m);
250
251 r = bus_message_from_malloc(bus, buffer, sz, NULL, 0, NULL, &m);
252 assert_se(r >= 0);
253
254 bus_message_dump(m, stdout, BUS_MESSAGE_DUMP_WITH_HEADER);
255
256 fclose(ms);
257 ms = open_memstream(&second, &second_size);
258 bus_message_dump(m, ms, 0);
259 fflush(ms);
260 assert_se(!ferror(ms));
261 assert_se(first_size == second_size);
262 assert_se(memcmp(first, second, first_size) == 0);
263
264 assert_se(sd_bus_message_rewind(m, true) >= 0);
265
266 r = sd_bus_message_read(m, "ssasg", &x, &x2, 2, &y, &z, &a_signature);
267 assert_se(r > 0);
268 assert_se(streq(x, "a string"));
269 assert_se(streq(x2, ""));
270 assert_se(streq(y, "string #1"));
271 assert_se(streq(z, "string #2"));
272 assert_se(streq(a_signature, "sba(tt)ss"));
273
274 r = sd_bus_message_read(m, "sass", &x, 5, &y, &z, &a, &b, &c, &d);
275 assert_se(r > 0);
276 assert_se(streq(x, "foobar"));
277 assert_se(streq(y, "foo"));
278 assert_se(streq(z, "bar"));
279 assert_se(streq(a, "waldo"));
280 assert_se(streq(b, "piep"));
281 assert_se(streq(c, "pap"));
282 assert_se(streq(d, "after"));
283
284 r = sd_bus_message_read(m, "a{yv}", 2, &u, "s", &x, &v, "s", &y);
285 assert_se(r > 0);
286 assert_se(u == 3);
287 assert_se(streq(x, "foo"));
288 assert_se(v == 5);
289 assert_se(streq(y, "waldo"));
290
291 r = sd_bus_message_read(m, "y(ty)", &v, &u64, &u);
292 assert_se(r > 0);
293 assert_se(v == 8);
294 assert_se(u64 == 777);
295 assert_se(u == 7);
296
297 r = sd_bus_message_read(m, "y(yt)", &v, &u, &u64);
298 assert_se(r > 0);
299 assert_se(v == 9);
300 assert_se(u == 77);
301 assert_se(u64 == 7777);
302
303 r = sd_bus_message_read(m, "y", &v);
304 assert_se(r > 0);
305 assert_se(v == 10);
306
307 r = sd_bus_message_read(m, "()");
308 assert_se(r > 0);
309
310 r = sd_bus_message_read(m, "ba(ss)", &boolean, 3, &x, &y, &a, &b, &c, &d);
311 assert_se(r > 0);
312 assert_se(boolean);
313 assert_se(streq(x, "aaa"));
314 assert_se(streq(y, "1"));
315 assert_se(streq(a, "bbb"));
316 assert_se(streq(b, "2"));
317 assert_se(streq(c, "ccc"));
318 assert_se(streq(d, "3"));
319
320 assert_se(sd_bus_message_verify_type(m, 'a', "s") > 0);
321
322 r = sd_bus_message_read(m, "as", 2, &x, &y);
323 assert_se(r > 0);
324 assert_se(streq(x, "foobar"));
325 assert_se(streq(y, "waldo"));
326
327 r = sd_bus_message_read_basic(m, 's', &s);
328 assert_se(r > 0);
329 assert_se(streq(s, "hallo"));
330
331 r = sd_bus_message_read_array(m, 'i', (const void**) &return_array, &sz);
332 assert_se(r > 0);
333 assert_se(sz == sizeof(integer_array));
334 assert_se(memcmp(integer_array, return_array, sz) == 0);
335
336 r = sd_bus_message_read_array(m, 'u', (const void**) &return_array, &sz);
337 assert_se(r > 0);
338 assert_se(sz == 0);
339
340 r = sd_bus_message_read(m, "a(stdo)", 1, &x, &u64, &dbl, &y);
341 assert_se(r > 0);
342 assert_se(streq(x, "foo"));
343 assert_se(u64 == 815ULL);
344 assert_se(fabs(dbl - 47.0) < 0.1);
345 assert_se(streq(y, "/"));
346
347 r = sd_bus_message_peek_type(m, NULL, NULL);
348 assert_se(r == 0);
349
350 r = sd_bus_message_new_method_call(bus, &copy, "foobar.waldo", "/", "foobar.waldo", "Piep");
351 assert_se(r >= 0);
352
353 r = sd_bus_message_rewind(m, true);
354 assert_se(r >= 0);
355
356 r = sd_bus_message_copy(copy, m, true);
357 assert_se(r >= 0);
358
359 r = bus_message_seal(copy, 4712, 0);
360 assert_se(r >= 0);
361
362 fclose(ms);
363 ms = open_memstream(&third, &third_size);
364 bus_message_dump(copy, ms, 0);
365 fflush(ms);
366 assert_se(!ferror(ms));
367
368 printf("<%.*s>\n", (int) first_size, first);
369 printf("<%.*s>\n", (int) third_size, third);
370
371 assert_se(first_size == third_size);
372 assert_se(memcmp(first, third, third_size) == 0);
373
374 r = sd_bus_message_rewind(m, true);
375 assert_se(r >= 0);
376
377 assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
378
379 r = sd_bus_message_skip(m, "ssasg");
380 assert_se(r > 0);
381
382 assert_se(sd_bus_message_verify_type(m, 's', NULL) > 0);
383
384 r = sd_bus_message_skip(m, "sass");
385 assert_se(r >= 0);
386
387 assert_se(sd_bus_message_verify_type(m, 'a', "{yv}") > 0);
388
389 r = sd_bus_message_skip(m, "a{yv}y(ty)y(yt)y()");
390 assert_se(r >= 0);
391
392 assert_se(sd_bus_message_verify_type(m, 'b', NULL) > 0);
393
394 r = sd_bus_message_read(m, "b", &boolean);
395 assert_se(r > 0);
396 assert_se(boolean);
397
398 r = sd_bus_message_enter_container(m, 0, NULL);
399 assert_se(r > 0);
400
401 r = sd_bus_message_read(m, "(ss)", &x, &y);
402 assert_se(r > 0);
403
404 r = sd_bus_message_read(m, "(ss)", &a, &b);
405 assert_se(r > 0);
406
407 r = sd_bus_message_read(m, "(ss)", &c, &d);
408 assert_se(r > 0);
409
410 r = sd_bus_message_read(m, "(ss)", &x, &y);
411 assert_se(r == 0);
412
413 r = sd_bus_message_exit_container(m);
414 assert_se(r >= 0);
415
416 assert_se(streq(x, "aaa"));
417 assert_se(streq(y, "1"));
418 assert_se(streq(a, "bbb"));
419 assert_se(streq(b, "2"));
420 assert_se(streq(c, "ccc"));
421 assert_se(streq(d, "3"));
422
423 test_bus_label_escape();
424 test_bus_path_encode();
425 test_bus_path_encode_unique();
426 test_bus_path_encode_many();
427
428 return 0;
429 }