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 33typedef struct { 34 DBusError e; 35} Fixture; 36 37typedef struct { 38 dbus_bool_t (*function) (const char *, DBusError *); 39 const char * const * valid; 40 const char * const * invalid; 41} Test; 42 43Test paths, interfaces, members, errors, bus_names, signatures, 44 single_signatures, strings; 45 46const 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 57const 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 70const char * const valid_interfaces[] = { 71 "com.example", 72 "com.example.a0", 73 "org.freedesktop.DBus", 74 NULL 75}; 76 77const 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 89const char * const valid_members[] = { 90 "_", 91 "a", 92 "a0", 93 "GetAll", 94 "BadgerMushroomSnake", 95 NULL 96}; 97 98const 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 111const char * const valid_errors[] = { 112 "com.example", 113 "com.example.a0", 114 "org.freedesktop.DBus.NameHasNoOwner", 115 NULL 116}; 117 118const 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 130const 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 141const 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 153const char * const valid_signatures[] = { 154 "", 155 "a{sv}", 156 NULL 157}; 158 159const char * const invalid_signatures[] = { 160 "a", 161 "a{s_}", 162 NULL 163}; 164 165const char * const valid_single_signatures[] = { 166 "s", 167 "a{sv}", 168 NULL 169}; 170 171const char * const invalid_single_signatures[] = { 172 "", 173 "a", 174 "sv", 175 "a{sv}as", 176 NULL 177}; 178 179const char * const valid_strings[] = { 180 "", 181 "\xc2\xa9", 182 NULL 183}; 184 185const char * const invalid_strings[] = { 186 "\xa9", 187 NULL 188}; 189 190static void 191setup (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 213static void 214test_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 259static void 260teardown (Fixture *f, 261 gconstpointer arg G_GNUC_UNUSED) 262{ 263 dbus_error_free (&f->e); 264} 265 266int 267main (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