1 /* Simple sanity-check for D-Bus syntax validation.
2 *
3 * Author: Simon McVittie <simon.mcvittie@collabora.co.uk>
4 * Copyright © 2010-2011 Nokia Corporation
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation files
8 * (the "Software"), to deal in the Software without restriction,
9 * including without limitation the rights to use, copy, modify, merge,
10 * publish, distribute, sublicense, and/or sell copies of the Software,
11 * and to permit persons to whom the Software is furnished to do so,
12 * subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be
15 * included in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
21 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
22 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
23 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 * SOFTWARE.
25 */
26
27 #include <config.h>
28
29 #include <glib.h>
30
31 #include <dbus/dbus.h>
32
33 typedef struct {
34 DBusError e;
35 } Fixture;
36
37 typedef struct {
38 dbus_bool_t (*function) (const char *, DBusError *);
39 const char * const * valid;
40 const char * const * invalid;
41 } Test;
42
43 Test paths, interfaces, members, errors, bus_names, signatures,
44 single_signatures, strings;
45
46 const char * const valid_paths[] = {
47 "/",
48 "/a",
49 "/_",
50 "/a/b/c",
51 "/com/example/123",
52 "/org/freedesktop/DBus",
53 "/org/freedesktop/Telepathy/AccountManager",
54 NULL
55 };
56
57 const char * const invalid_paths[] = {
58 "",
59 ".",
60 "//",
61 "/a/",
62 "/-",
63 "/com//example/MyApp",
64 "/$",
65 "/\xa9", /* © in latin-1 */
66 "/\xc2\xa9", /* © in UTF-8 */
67 NULL
68 };
69
70 const char * const valid_interfaces[] = {
71 "com.example",
72 "com.example.a0",
73 "org.freedesktop.DBus",
74 NULL
75 };
76
77 const char * const invalid_interfaces[] = {
78 "",
79 "com",
80 "com.example.",
81 "com.example..a0",
82 "com.example.0a",
83 "com.example.a$",
84 "com.example.a\xa9",
85 "com.example.a\xc2\xa9",
86 NULL
87 };
88
89 const char * const valid_members[] = {
90 "_",
91 "a",
92 "a0",
93 "GetAll",
94 "BadgerMushroomSnake",
95 NULL
96 };
97
98 const char * const invalid_members[] = {
99 "",
100 "-",
101 "a-",
102 "0",
103 "0_",
104 "Badger.Mushroom",
105 "a$",
106 "a\xa9",
107 "a\xc2\xa9",
108 NULL
109 };
110
111 const char * const valid_errors[] = {
112 "com.example",
113 "com.example.a0",
114 "org.freedesktop.DBus.NameHasNoOwner",
115 NULL
116 };
117
118 const char * const invalid_errors[] = {
119 "",
120 "com",
121 "com.example.",
122 "com.example..a0",
123 "com.example.0a",
124 "com.example.a$",
125 "com.example.a\xa9",
126 "com.example.a\xc2\xa9",
127 NULL
128 };
129
130 const char * const valid_bus_names[] = {
131 "com.example",
132 "com.example.a0",
133 "com.example._",
134 ":1.42",
135 ":1.2.3.4.5",
136 ":com.example",
137 "org.freedesktop.DBus",
138 NULL
139 };
140
141 const char * const invalid_bus_names[] = {
142 "",
143 "com",
144 "com.example.",
145 "com.example..a0",
146 "com.example.0a",
147 "com.example.a:b",
148 "com.example.a\xa9",
149 "com.example.a\xc2\xa9",
150 NULL
151 };
152
153 const char * const valid_signatures[] = {
154 "",
155 "a{sv}",
156 NULL
157 };
158
159 const char * const invalid_signatures[] = {
160 "a",
161 "a{s_}",
162 NULL
163 };
164
165 const char * const valid_single_signatures[] = {
166 "s",
167 "a{sv}",
168 NULL
169 };
170
171 const char * const invalid_single_signatures[] = {
172 "",
173 "a",
174 "sv",
175 "a{sv}as",
176 NULL
177 };
178
179 const char * const valid_strings[] = {
180 "",
181 "\xc2\xa9",
182 NULL
183 };
184
185 const char * const invalid_strings[] = {
186 "\xa9",
187 NULL
188 };
189
190 static void
setup(Fixture * f,gconstpointer arg G_GNUC_UNUSED)191 setup (Fixture *f,
192 gconstpointer arg G_GNUC_UNUSED)
193 {
194 dbus_error_init (&f->e);
195
196 #define FILL_TEST(name, func) \
197 do { \
198 (name).function = (func); \
199 (name).valid = valid_ ## name; \
200 (name).invalid = invalid_ ## name; \
201 } while (0)
202
203 FILL_TEST (paths, dbus_validate_path);
204 FILL_TEST (interfaces, dbus_validate_interface);
205 FILL_TEST (members, dbus_validate_member);
206 FILL_TEST (errors, dbus_validate_error_name);
207 FILL_TEST (bus_names, dbus_validate_bus_name);
208 FILL_TEST (signatures, dbus_signature_validate);
209 FILL_TEST (single_signatures, dbus_signature_validate_single);
210 FILL_TEST (strings, dbus_validate_utf8);
211 }
212
213 static void
test_syntax(Fixture * f,gconstpointer arg)214 test_syntax (Fixture *f,
215 gconstpointer arg)
216 {
217 const Test *test = arg;
218 int i;
219
220 g_assert (test != NULL);
221 g_assert (test->function != NULL);
222 g_assert (test->valid != NULL);
223 g_assert (test->invalid != NULL);
224
225 for (i = 0; test->valid[i] != NULL; i++)
226 {
227 dbus_bool_t ok = test->function (test->valid[i], &f->e);
228
229 if (dbus_error_is_set (&f->e))
230 g_error ("%s was considered invalid: %s: %s", test->valid[i],
231 f->e.name, f->e.message);
232
233 if (!ok)
234 g_error ("%s was considered invalid without an error", test->valid[i]);
235 }
236
237 for (i = 0; test->invalid[i] != NULL; i++)
238 {
239 dbus_bool_t ok = test->function (test->invalid[i], &f->e);
240
241 if (ok)
242 g_error ("%s should have been considered invalid", test->invalid[i]);
243
244 if (!dbus_error_is_set (&f->e))
245 g_error ("%s should have an error set", test->invalid[i]);
246
247 if (!dbus_validate_error_name (f->e.name, NULL))
248 g_error ("%s produced an invalid error name: %s",
249 test->invalid[i], f->e.name);
250
251 if (!dbus_validate_utf8 (f->e.message, NULL))
252 g_error ("%s produced an invalid error message: %s",
253 test->invalid[i], f->e.message);
254
255 dbus_error_free (&f->e);
256 }
257 }
258
259 static void
teardown(Fixture * f,gconstpointer arg G_GNUC_UNUSED)260 teardown (Fixture *f,
261 gconstpointer arg G_GNUC_UNUSED)
262 {
263 dbus_error_free (&f->e);
264 }
265
266 int
main(int argc,char ** argv)267 main (int argc,
268 char **argv)
269 {
270 g_test_init (&argc, &argv, NULL);
271
272 g_test_add ("/syntax/path", Fixture, &paths, setup, test_syntax, teardown);
273 g_test_add ("/syntax/interface", Fixture, &interfaces,
274 setup, test_syntax, teardown);
275 g_test_add ("/syntax/error", Fixture, &errors,
276 setup, test_syntax, teardown);
277 g_test_add ("/syntax/member", Fixture, &members,
278 setup, test_syntax, teardown);
279 g_test_add ("/syntax/bus-name", Fixture, &bus_names,
280 setup, test_syntax, teardown);
281 g_test_add ("/syntax/signature", Fixture, &signatures,
282 setup, test_syntax, teardown);
283 g_test_add ("/syntax/single-signature", Fixture, &single_signatures,
284 setup, test_syntax, teardown);
285 g_test_add ("/syntax/utf8", Fixture, &strings,
286 setup, test_syntax, teardown);
287
288 return g_test_run ();
289 }
290