Home | History | Annotate | Download | only in test
      1 /* Simple sanity-check for D-Bus syntax validation.
      2  *
      3  * Author: Simon McVittie <simon.mcvittie (at) 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
    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
    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
    260 teardown (Fixture *f,
    261     gconstpointer arg G_GNUC_UNUSED)
    262 {
    263   dbus_error_free (&f->e);
    264 }
    265 
    266 int
    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