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