/* Simple sanity-check for D-Bus syntax validation. * * Author: Simon McVittie * Copyright © 2010-2011 Nokia Corporation * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #include #include #include typedef struct { DBusError e; } Fixture; typedef struct { dbus_bool_t (*function) (const char *, DBusError *); const char * const * valid; const char * const * invalid; } Test; Test paths, interfaces, members, errors, bus_names, signatures, single_signatures, strings; const char * const valid_paths[] = { "/", "/a", "/_", "/a/b/c", "/com/example/123", "/org/freedesktop/DBus", "/org/freedesktop/Telepathy/AccountManager", NULL }; const char * const invalid_paths[] = { "", ".", "//", "/a/", "/-", "/com//example/MyApp", "/$", "/\xa9", /* © in latin-1 */ "/\xc2\xa9", /* © in UTF-8 */ NULL }; const char * const valid_interfaces[] = { "com.example", "com.example.a0", "org.freedesktop.DBus", NULL }; const char * const invalid_interfaces[] = { "", "com", "com.example.", "com.example..a0", "com.example.0a", "com.example.a$", "com.example.a\xa9", "com.example.a\xc2\xa9", NULL }; const char * const valid_members[] = { "_", "a", "a0", "GetAll", "BadgerMushroomSnake", NULL }; const char * const invalid_members[] = { "", "-", "a-", "0", "0_", "Badger.Mushroom", "a$", "a\xa9", "a\xc2\xa9", NULL }; const char * const valid_errors[] = { "com.example", "com.example.a0", "org.freedesktop.DBus.NameHasNoOwner", NULL }; const char * const invalid_errors[] = { "", "com", "com.example.", "com.example..a0", "com.example.0a", "com.example.a$", "com.example.a\xa9", "com.example.a\xc2\xa9", NULL }; const char * const valid_bus_names[] = { "com.example", "com.example.a0", "com.example._", ":1.42", ":1.2.3.4.5", ":com.example", "org.freedesktop.DBus", NULL }; const char * const invalid_bus_names[] = { "", "com", "com.example.", "com.example..a0", "com.example.0a", "com.example.a:b", "com.example.a\xa9", "com.example.a\xc2\xa9", NULL }; const char * const valid_signatures[] = { "", "a{sv}", NULL }; const char * const invalid_signatures[] = { "a", "a{s_}", NULL }; const char * const valid_single_signatures[] = { "s", "a{sv}", NULL }; const char * const invalid_single_signatures[] = { "", "a", "sv", "a{sv}as", NULL }; const char * const valid_strings[] = { "", "\xc2\xa9", /* UTF-8 (c) symbol */ "\xef\xbf\xbe", /* U+FFFE is reserved but Corrigendum 9 says it's OK */ NULL }; const char * const invalid_strings[] = { "\xa9", /* Latin-1 (c) symbol */ "\xed\xa0\x80", /* UTF-16 surrogates are not valid in UTF-8 */ NULL }; static void setup (Fixture *f, gconstpointer arg G_GNUC_UNUSED) { dbus_error_init (&f->e); #define FILL_TEST(name, func) \ do { \ (name).function = (func); \ (name).valid = valid_ ## name; \ (name).invalid = invalid_ ## name; \ } while (0) FILL_TEST (paths, dbus_validate_path); FILL_TEST (interfaces, dbus_validate_interface); FILL_TEST (members, dbus_validate_member); FILL_TEST (errors, dbus_validate_error_name); FILL_TEST (bus_names, dbus_validate_bus_name); FILL_TEST (signatures, dbus_signature_validate); FILL_TEST (single_signatures, dbus_signature_validate_single); FILL_TEST (strings, dbus_validate_utf8); } static void test_syntax (Fixture *f, gconstpointer arg) { const Test *test = arg; int i; g_assert (test != NULL); g_assert (test->function != NULL); g_assert (test->valid != NULL); g_assert (test->invalid != NULL); for (i = 0; test->valid[i] != NULL; i++) { dbus_bool_t ok = test->function (test->valid[i], &f->e); if (dbus_error_is_set (&f->e)) g_error ("%s was considered invalid: %s: %s", test->valid[i], f->e.name, f->e.message); if (!ok) g_error ("%s was considered invalid without an error", test->valid[i]); } for (i = 0; test->invalid[i] != NULL; i++) { dbus_bool_t ok = test->function (test->invalid[i], &f->e); if (ok) g_error ("%s should have been considered invalid", test->invalid[i]); if (!dbus_error_is_set (&f->e)) g_error ("%s should have an error set", test->invalid[i]); if (!dbus_validate_error_name (f->e.name, NULL)) g_error ("%s produced an invalid error name: %s", test->invalid[i], f->e.name); if (!dbus_validate_utf8 (f->e.message, NULL)) g_error ("%s produced an invalid error message: %s", test->invalid[i], f->e.message); dbus_error_free (&f->e); } } static void teardown (Fixture *f, gconstpointer arg G_GNUC_UNUSED) { dbus_error_free (&f->e); } int main (int argc, char **argv) { g_test_init (&argc, &argv, NULL); g_test_add ("/syntax/path", Fixture, &paths, setup, test_syntax, teardown); g_test_add ("/syntax/interface", Fixture, &interfaces, setup, test_syntax, teardown); g_test_add ("/syntax/error", Fixture, &errors, setup, test_syntax, teardown); g_test_add ("/syntax/member", Fixture, &members, setup, test_syntax, teardown); g_test_add ("/syntax/bus-name", Fixture, &bus_names, setup, test_syntax, teardown); g_test_add ("/syntax/signature", Fixture, &signatures, setup, test_syntax, teardown); g_test_add ("/syntax/single-signature", Fixture, &single_signatures, setup, test_syntax, teardown); g_test_add ("/syntax/utf8", Fixture, &strings, setup, test_syntax, teardown); return g_test_run (); }