bus: Assign a serial number for messages from the driver
[platform/upstream/dbus.git] / test / syntax.c
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 #include "test-utils-glib.h"
34
35 typedef struct {
36     DBusError e;
37 } Fixture;
38
39 typedef struct {
40     dbus_bool_t (*function) (const char *, DBusError *);
41     const char * const * valid;
42     const char * const * invalid;
43 } Test;
44
45 Test paths, interfaces, members, errors, bus_names, signatures,
46      single_signatures, strings;
47
48 const char * const valid_paths[] = {
49     "/",
50     "/a",
51     "/_",
52     "/a/b/c",
53     "/com/example/123",
54     "/org/freedesktop/DBus",
55     "/org/freedesktop/Telepathy/AccountManager",
56     NULL
57 };
58
59 const char * const invalid_paths[] = {
60     "",
61     ".",
62     "//",
63     "/a/",
64     "/-",
65     "/com//example/MyApp",
66     "/$",
67     "/\xa9",      /* © in latin-1 */
68     "/\xc2\xa9",  /* © in UTF-8 */
69     NULL
70 };
71
72 const char * const valid_interfaces[] = {
73     "com.example",
74     "com.example.a0",
75     "org.freedesktop.DBus",
76     NULL
77 };
78
79 const char * const invalid_interfaces[] = {
80    "",
81     "com",
82     "com.example.",
83     "com.example..a0",
84     "com.example.0a",
85     "com.example.a$",
86     "com.example.a\xa9",
87     "com.example.a\xc2\xa9",
88     NULL
89 };
90
91 const char * const valid_members[] = {
92     "_",
93     "a",
94     "a0",
95     "GetAll",
96     "BadgerMushroomSnake",
97     NULL
98 };
99
100 const char * const invalid_members[] = {
101     "",
102     "-",
103     "a-",
104     "0",
105     "0_",
106     "Badger.Mushroom",
107     "a$",
108     "a\xa9",
109     "a\xc2\xa9",
110     NULL
111 };
112
113 const char * const valid_errors[] = {
114     "com.example",
115     "com.example.a0",
116     "org.freedesktop.DBus.NameHasNoOwner",
117     NULL
118 };
119
120 const char * const invalid_errors[] = {
121    "",
122     "com",
123     "com.example.",
124     "com.example..a0",
125     "com.example.0a",
126     "com.example.a$",
127     "com.example.a\xa9",
128     "com.example.a\xc2\xa9",
129     NULL
130 };
131
132 const char * const valid_bus_names[] = {
133     "com.example",
134     "com.example.a0",
135     "com.example._",
136     ":1.42",
137     ":1.2.3.4.5",
138     ":com.example",
139     "org.freedesktop.DBus",
140     NULL
141 };
142
143 const char * const invalid_bus_names[] = {
144    "",
145     "com",
146     "com.example.",
147     "com.example..a0",
148     "com.example.0a",
149     "com.example.a:b",
150     "com.example.a\xa9",
151     "com.example.a\xc2\xa9",
152     NULL
153 };
154
155 const char * const valid_signatures[] = {
156     "",
157     "a{sv}",
158     NULL
159 };
160
161 const char * const invalid_signatures[] = {
162     "a",
163     "a{s_}",
164     NULL
165 };
166
167 const char * const valid_single_signatures[] = {
168     "s",
169     "a{sv}",
170     NULL
171 };
172
173 const char * const invalid_single_signatures[] = {
174     "",
175     "a",
176     "sv",
177     "a{sv}as",
178     NULL
179 };
180
181 const char * const valid_strings[] = {
182     "",
183     "\xc2\xa9",       /* UTF-8 (c) symbol */
184     "\xef\xbf\xbe",   /* U+FFFE is reserved but Corrigendum 9 says it's OK */
185     NULL
186 };
187
188 const char * const invalid_strings[] = {
189     "\xa9",           /* Latin-1 (c) symbol */
190     "\xed\xa0\x80",   /* UTF-16 surrogates are not valid in UTF-8 */
191     NULL
192 };
193
194 static void
195 setup (Fixture *f,
196     gconstpointer arg G_GNUC_UNUSED)
197 {
198   dbus_error_init (&f->e);
199
200 #define FILL_TEST(name, func) \
201   do { \
202     (name).function = (func); \
203     (name).valid = valid_ ## name; \
204     (name).invalid = invalid_ ## name; \
205   } while (0)
206
207   FILL_TEST (paths, dbus_validate_path);
208   FILL_TEST (interfaces, dbus_validate_interface);
209   FILL_TEST (members, dbus_validate_member);
210   FILL_TEST (errors, dbus_validate_error_name);
211   FILL_TEST (bus_names, dbus_validate_bus_name);
212   FILL_TEST (signatures, dbus_signature_validate);
213   FILL_TEST (single_signatures, dbus_signature_validate_single);
214   FILL_TEST (strings, dbus_validate_utf8);
215 }
216
217 static void
218 test_syntax (Fixture *f,
219     gconstpointer arg)
220 {
221   const Test *test = arg;
222   int i;
223
224   g_assert (test != NULL);
225   g_assert (test->function != NULL);
226   g_assert (test->valid != NULL);
227   g_assert (test->invalid != NULL);
228
229   for (i = 0; test->valid[i] != NULL; i++)
230     {
231       dbus_bool_t ok = test->function (test->valid[i], &f->e);
232
233       if (dbus_error_is_set (&f->e))
234         g_error ("%s was considered invalid: %s: %s", test->valid[i],
235             f->e.name, f->e.message);
236
237       if (!ok)
238         g_error ("%s was considered invalid without an error", test->valid[i]);
239     }
240
241   for (i = 0; test->invalid[i] != NULL; i++)
242     {
243       dbus_bool_t ok = test->function (test->invalid[i], &f->e);
244
245       if (ok)
246         g_error ("%s should have been considered invalid", test->invalid[i]);
247
248       if (!dbus_error_is_set (&f->e))
249         g_error ("%s should have an error set", test->invalid[i]);
250
251       if (!dbus_validate_error_name (f->e.name, NULL))
252         g_error ("%s produced an invalid error name: %s",
253             test->invalid[i], f->e.name);
254
255       if (!dbus_validate_utf8 (f->e.message, NULL))
256         g_error ("%s produced an invalid error message: %s",
257             test->invalid[i], f->e.message);
258
259       dbus_error_free (&f->e);
260     }
261 }
262
263 static void
264 teardown (Fixture *f,
265     gconstpointer arg G_GNUC_UNUSED)
266 {
267   dbus_error_free (&f->e);
268 }
269
270 int
271 main (int argc,
272     char **argv)
273 {
274   test_init (&argc, &argv);
275
276   g_test_add ("/syntax/path", Fixture, &paths, setup, test_syntax, teardown);
277   g_test_add ("/syntax/interface", Fixture, &interfaces,
278       setup, test_syntax, teardown);
279   g_test_add ("/syntax/error", Fixture, &errors,
280       setup, test_syntax, teardown);
281   g_test_add ("/syntax/member", Fixture, &members,
282       setup, test_syntax, teardown);
283   g_test_add ("/syntax/bus-name", Fixture, &bus_names,
284       setup, test_syntax, teardown);
285   g_test_add ("/syntax/signature", Fixture, &signatures,
286       setup, test_syntax, teardown);
287   g_test_add ("/syntax/single-signature", Fixture, &single_signatures,
288       setup, test_syntax, teardown);
289   g_test_add ("/syntax/utf8", Fixture, &strings,
290       setup, test_syntax, teardown);
291
292   return g_test_run ();
293 }