dbus-marshal-validate-util.c

00001 /* -*- mode: C; c-file-style: "gnu" -*- */
00002 /* dbus-marshal-validate-util.c Would be in dbus-marshal-validate.c, but only used by tests/bus
00003  *
00004  * Copyright (C) 2005 Red Hat, Inc.
00005  *
00006  * Licensed under the Academic Free License version 2.1
00007  *
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00021  *
00022  */
00023 
00024 #include <config.h>
00025 #ifdef DBUS_BUILD_TESTS
00026 
00027 #ifndef DOXYGEN_SHOULD_SKIP_THIS
00028 
00029 #include "dbus-internals.h"
00030 #include "dbus-marshal-validate.h"
00031 #include "dbus-marshal-recursive.h"
00032 
00033 #include "dbus-test.h"
00034 #include <stdio.h>
00035 
00036 typedef struct
00037 {
00038   const char *data;
00039   DBusValidity expected;
00040 } ValidityTest;
00041 
00042 static void
00043 run_validity_tests (const ValidityTest *tests,
00044                     int                 n_tests,
00045                     DBusValidity (* func) (const DBusString*,int,int))
00046 {
00047   int i;
00048 
00049   for (i = 0; i < n_tests; i++)
00050     {
00051       DBusString str;
00052       DBusValidity v;
00053 
00054       _dbus_string_init_const (&str, tests[i].data);
00055 
00056       v = (*func) (&str, 0, _dbus_string_get_length (&str));
00057 
00058       if (v != tests[i].expected)
00059         {
00060           _dbus_warn ("Improper validation result %d for '%s'\n",
00061                       v, tests[i].data);
00062           _dbus_assert_not_reached ("test failed");
00063         }
00064 
00065       ++i;
00066     }
00067 }
00068 
00069 static const ValidityTest signature_tests[] = {
00070   { "", DBUS_VALID },
00071   { "i", DBUS_VALID },
00072   { "ai", DBUS_VALID },
00073   { "(i)", DBUS_VALID },
00074   { "w", DBUS_INVALID_UNKNOWN_TYPECODE },
00075   { "a", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE },
00076   { "aaaaaa", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE },
00077   { "ii(ii)a", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE },
00078   { "ia", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE },
00079   /* DBUS_INVALID_SIGNATURE_TOO_LONG, */ /* too hard to test this way */
00080   { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
00081     DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION },
00082   { "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((ii))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))",
00083     DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION },
00084   { ")", DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED },
00085   { "i)", DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED },
00086   { "a)", DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED },
00087   { "(", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED },
00088   { "(i", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED },
00089   { "(iiiii", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED },
00090   { "(ai", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED },
00091   { "()", DBUS_INVALID_STRUCT_HAS_NO_FIELDS },
00092   { "(())", DBUS_INVALID_STRUCT_HAS_NO_FIELDS },
00093   { "a()", DBUS_INVALID_STRUCT_HAS_NO_FIELDS },
00094   { "i()", DBUS_INVALID_STRUCT_HAS_NO_FIELDS },
00095   { "()i", DBUS_INVALID_STRUCT_HAS_NO_FIELDS },
00096   { "(a)", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE },
00097   { "a{ia}", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE },
00098   { "a{}", DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS },
00099   { "a{aii}", DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE },
00100   /* { "a{i}", DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD }, */
00101   /* { "{is}", DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY }, */
00102   /* { "a{isi}", DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS }, */
00103 };
00104 
00105 dbus_bool_t
00106 _dbus_marshal_validate_test (void)
00107 {
00108   DBusString str;
00109   int i;
00110 
00111   const char *valid_paths[] = {
00112     "/",
00113     "/foo/bar",
00114     "/foo",
00115     "/foo/bar/baz"
00116   };
00117   const char *invalid_paths[] = {
00118     "bar",
00119     "bar/baz",
00120     "/foo/bar/",
00121     "/foo/"
00122     "foo/",
00123     "boo//blah",
00124     "//",
00125     "///",
00126     "foo///blah/",
00127     "Hello World",
00128     "",
00129     "   ",
00130     "foo bar"
00131   };
00132 
00133   const char *valid_interfaces[] = {
00134     "org.freedesktop.Foo",
00135     "Bar.Baz",
00136     "Blah.Blah.Blah.Blah.Blah",
00137     "a.b",
00138     "a.b.c.d.e.f.g",
00139     "a0.b1.c2.d3.e4.f5.g6",
00140     "abc123.foo27"
00141   };
00142   const char *invalid_interfaces[] = {
00143     ".",
00144     "",
00145     "..",
00146     ".Foo.Bar",
00147     "..Foo.Bar",
00148     "Foo.Bar.",
00149     "Foo.Bar..",
00150     "Foo",
00151     "9foo.bar.baz",
00152     "foo.bar..baz",
00153     "foo.bar...baz",
00154     "foo.bar.b..blah",
00155     ":",
00156     ":0-1",
00157     "10",
00158     ":11.34324",
00159     "0.0.0",
00160     "0..0",
00161     "foo.Bar.%",
00162     "foo.Bar!!",
00163     "!Foo.bar.bz",
00164     "foo.$.blah",
00165     "",
00166     "   ",
00167     "foo bar"
00168   };
00169 
00170   const char *valid_unique_names[] = {
00171     ":0",
00172     ":a",
00173     ":",
00174     ":.a",
00175     ":.1",
00176     ":0.1",
00177     ":000.2222",
00178     ":.blah",
00179     ":abce.freedesktop.blah"
00180   };
00181   const char *invalid_unique_names[] = {
00182     //":-",
00183     ":!",
00184     //":0-10",
00185     ":blah.",
00186     ":blah.",
00187     ":blah..org",
00188     ":blah.org..",
00189     ":..blah.org",
00190     "",
00191     "   ",
00192     "foo bar"
00193   };
00194 
00195   const char *valid_members[] = {
00196     "Hello",
00197     "Bar",
00198     "foobar",
00199     "_foobar",
00200     "foo89"
00201   };
00202 
00203   const char *invalid_members[] = {
00204     "9Hello",
00205     "10",
00206     "1",
00207     "foo-bar",
00208     "blah.org",
00209     ".blah",
00210     "blah.",
00211     "Hello.",
00212     "!foo",
00213     "",
00214     "   ",
00215     "foo bar"
00216   };
00217 
00218   const char *valid_signatures[] = {
00219     "",
00220     "sss",
00221     "i",
00222     "b"
00223   };
00224 
00225   const char *invalid_signatures[] = {
00226     " ",
00227     "not a valid signature",
00228     "123",
00229     ".",
00230     "("
00231   };
00232 
00233   /* Signature with reason */
00234 
00235   run_validity_tests (signature_tests, _DBUS_N_ELEMENTS (signature_tests),
00236                       _dbus_validate_signature_with_reason);
00237 
00238   /* Path validation */
00239   i = 0;
00240   while (i < (int) _DBUS_N_ELEMENTS (valid_paths))
00241     {
00242       _dbus_string_init_const (&str, valid_paths[i]);
00243 
00244       if (!_dbus_validate_path (&str, 0,
00245                                 _dbus_string_get_length (&str)))
00246         {
00247           _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]);
00248           _dbus_assert_not_reached ("invalid path");
00249         }
00250 
00251       ++i;
00252     }
00253 
00254   i = 0;
00255   while (i < (int) _DBUS_N_ELEMENTS (invalid_paths))
00256     {
00257       _dbus_string_init_const (&str, invalid_paths[i]);
00258 
00259       if (_dbus_validate_path (&str, 0,
00260                                _dbus_string_get_length (&str)))
00261         {
00262           _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]);
00263           _dbus_assert_not_reached ("valid path");
00264         }
00265 
00266       ++i;
00267     }
00268 
00269   /* Interface validation */
00270   i = 0;
00271   while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
00272     {
00273       _dbus_string_init_const (&str, valid_interfaces[i]);
00274 
00275       if (!_dbus_validate_interface (&str, 0,
00276                                      _dbus_string_get_length (&str)))
00277         {
00278           _dbus_warn ("Interface \"%s\" should have been valid\n", valid_interfaces[i]);
00279           _dbus_assert_not_reached ("invalid interface");
00280         }
00281 
00282       ++i;
00283     }
00284 
00285   i = 0;
00286   while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
00287     {
00288       _dbus_string_init_const (&str, invalid_interfaces[i]);
00289 
00290       if (_dbus_validate_interface (&str, 0,
00291                                     _dbus_string_get_length (&str)))
00292         {
00293           _dbus_warn ("Interface \"%s\" should have been invalid\n", invalid_interfaces[i]);
00294           _dbus_assert_not_reached ("valid interface");
00295         }
00296 
00297       ++i;
00298     }
00299 
00300   /* Bus name validation (check that valid interfaces are valid bus names,
00301    * and invalid interfaces are invalid services except if they start with ':')
00302    */
00303   i = 0;
00304   while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
00305     {
00306       _dbus_string_init_const (&str, valid_interfaces[i]);
00307 
00308       if (!_dbus_validate_bus_name (&str, 0,
00309                                    _dbus_string_get_length (&str)))
00310         {
00311           _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_interfaces[i]);
00312           _dbus_assert_not_reached ("invalid bus name");
00313         }
00314 
00315       ++i;
00316     }
00317 
00318   i = 0;
00319   while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
00320     {
00321       if (invalid_interfaces[i][0] != ':')
00322         {
00323           _dbus_string_init_const (&str, invalid_interfaces[i]);
00324 
00325           if (_dbus_validate_bus_name (&str, 0,
00326                                        _dbus_string_get_length (&str)))
00327             {
00328               _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_interfaces[i]);
00329               _dbus_assert_not_reached ("valid bus name");
00330             }
00331         }
00332 
00333       ++i;
00334     }
00335 
00336   /* unique name validation */
00337   i = 0;
00338   while (i < (int) _DBUS_N_ELEMENTS (valid_unique_names))
00339     {
00340       _dbus_string_init_const (&str, valid_unique_names[i]);
00341 
00342       if (!_dbus_validate_bus_name (&str, 0,
00343                                     _dbus_string_get_length (&str)))
00344         {
00345           _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_unique_names[i]);
00346           _dbus_assert_not_reached ("invalid unique name");
00347         }
00348 
00349       ++i;
00350     }
00351 
00352   i = 0;
00353   while (i < (int) _DBUS_N_ELEMENTS (invalid_unique_names))
00354     {
00355       _dbus_string_init_const (&str, invalid_unique_names[i]);
00356 
00357       if (_dbus_validate_bus_name (&str, 0,
00358                                    _dbus_string_get_length (&str)))
00359         {
00360           _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_unique_names[i]);
00361           _dbus_assert_not_reached ("valid unique name");
00362         }
00363 
00364       ++i;
00365     }
00366 
00367 
00368   /* Error name validation (currently identical to interfaces)
00369    */
00370   i = 0;
00371   while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces))
00372     {
00373       _dbus_string_init_const (&str, valid_interfaces[i]);
00374 
00375       if (!_dbus_validate_error_name (&str, 0,
00376                                       _dbus_string_get_length (&str)))
00377         {
00378           _dbus_warn ("Error name \"%s\" should have been valid\n", valid_interfaces[i]);
00379           _dbus_assert_not_reached ("invalid error name");
00380         }
00381 
00382       ++i;
00383     }
00384 
00385   i = 0;
00386   while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces))
00387     {
00388       if (invalid_interfaces[i][0] != ':')
00389         {
00390           _dbus_string_init_const (&str, invalid_interfaces[i]);
00391 
00392           if (_dbus_validate_error_name (&str, 0,
00393                                          _dbus_string_get_length (&str)))
00394             {
00395               _dbus_warn ("Error name \"%s\" should have been invalid\n", invalid_interfaces[i]);
00396               _dbus_assert_not_reached ("valid error name");
00397             }
00398         }
00399 
00400       ++i;
00401     }
00402 
00403   /* Member validation */
00404   i = 0;
00405   while (i < (int) _DBUS_N_ELEMENTS (valid_members))
00406     {
00407       _dbus_string_init_const (&str, valid_members[i]);
00408 
00409       if (!_dbus_validate_member (&str, 0,
00410                                   _dbus_string_get_length (&str)))
00411         {
00412           _dbus_warn ("Member \"%s\" should have been valid\n", valid_members[i]);
00413           _dbus_assert_not_reached ("invalid member");
00414         }
00415 
00416       ++i;
00417     }
00418 
00419   i = 0;
00420   while (i < (int) _DBUS_N_ELEMENTS (invalid_members))
00421     {
00422       _dbus_string_init_const (&str, invalid_members[i]);
00423 
00424       if (_dbus_validate_member (&str, 0,
00425                                  _dbus_string_get_length (&str)))
00426         {
00427           _dbus_warn ("Member \"%s\" should have been invalid\n", invalid_members[i]);
00428           _dbus_assert_not_reached ("valid member");
00429         }
00430 
00431       ++i;
00432     }
00433 
00434   /* Signature validation */
00435   i = 0;
00436   while (i < (int) _DBUS_N_ELEMENTS (valid_signatures))
00437     {
00438       _dbus_string_init_const (&str, valid_signatures[i]);
00439 
00440       if (!_dbus_validate_signature (&str, 0,
00441                                      _dbus_string_get_length (&str)))
00442         {
00443           _dbus_warn ("Signature \"%s\" should have been valid\n", valid_signatures[i]);
00444           _dbus_assert_not_reached ("invalid signature");
00445         }
00446 
00447       ++i;
00448     }
00449 
00450   i = 0;
00451   while (i < (int) _DBUS_N_ELEMENTS (invalid_signatures))
00452     {
00453       _dbus_string_init_const (&str, invalid_signatures[i]);
00454 
00455       if (_dbus_validate_signature (&str, 0,
00456                                     _dbus_string_get_length (&str)))
00457         {
00458           _dbus_warn ("Signature \"%s\" should have been invalid\n", invalid_signatures[i]);
00459           _dbus_assert_not_reached ("valid signature");
00460         }
00461 
00462       ++i;
00463     }
00464 
00465   /* Validate claimed length longer than real length */
00466   _dbus_string_init_const (&str, "abc.efg");
00467   if (_dbus_validate_bus_name (&str, 0, 8))
00468     _dbus_assert_not_reached ("validated too-long string");
00469   if (_dbus_validate_interface (&str, 0, 8))
00470     _dbus_assert_not_reached ("validated too-long string");
00471   if (_dbus_validate_error_name (&str, 0, 8))
00472     _dbus_assert_not_reached ("validated too-long string");
00473 
00474   _dbus_string_init_const (&str, "abc");
00475   if (_dbus_validate_member (&str, 0, 4))
00476     _dbus_assert_not_reached ("validated too-long string");
00477 
00478   _dbus_string_init_const (&str, "sss");
00479   if (_dbus_validate_signature (&str, 0, 4))
00480     _dbus_assert_not_reached ("validated too-long signature");
00481 
00482   /* Validate string exceeding max name length */
00483   if (!_dbus_string_init (&str))
00484     _dbus_assert_not_reached ("no memory");
00485 
00486   while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
00487     if (!_dbus_string_append (&str, "abc.def"))
00488       _dbus_assert_not_reached ("no memory");
00489 
00490   if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
00491     _dbus_assert_not_reached ("validated overmax string");
00492   if (_dbus_validate_interface (&str, 0, _dbus_string_get_length (&str)))
00493     _dbus_assert_not_reached ("validated overmax string");
00494   if (_dbus_validate_error_name (&str, 0, _dbus_string_get_length (&str)))
00495     _dbus_assert_not_reached ("validated overmax string");
00496 
00497   /* overlong member */
00498   _dbus_string_set_length (&str, 0);
00499   while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
00500     if (!_dbus_string_append (&str, "abc"))
00501       _dbus_assert_not_reached ("no memory");
00502 
00503   if (_dbus_validate_member (&str, 0, _dbus_string_get_length (&str)))
00504     _dbus_assert_not_reached ("validated overmax string");
00505 
00506   /* overlong unique name */
00507   _dbus_string_set_length (&str, 0);
00508   _dbus_string_append (&str, ":");
00509   while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH)
00510     if (!_dbus_string_append (&str, "abc"))
00511       _dbus_assert_not_reached ("no memory");
00512 
00513   if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str)))
00514     _dbus_assert_not_reached ("validated overmax string");
00515 
00516   _dbus_string_free (&str);
00517 
00518   /* Body validation; test basic validation of valid bodies for both endian */
00519   
00520   {
00521     int sequence;
00522     DBusString signature;
00523     DBusString body;
00524 
00525     if (!_dbus_string_init (&signature) || !_dbus_string_init (&body))
00526       _dbus_assert_not_reached ("oom");
00527 
00528     sequence = 0;
00529     while (dbus_internal_do_not_use_generate_bodies (sequence,
00530                                                      DBUS_LITTLE_ENDIAN,
00531                                                      &signature, &body))
00532       {
00533         DBusValidity validity;
00534 
00535         validity = _dbus_validate_body_with_reason (&signature, 0,
00536                                                     DBUS_LITTLE_ENDIAN,
00537                                                     NULL, &body, 0,
00538                                                     _dbus_string_get_length (&body));
00539         if (validity != DBUS_VALID)
00540           {
00541             _dbus_warn ("invalid code %d expected valid on sequence %d little endian\n",
00542                         validity, sequence);
00543             _dbus_verbose_bytes_of_string (&signature, 0, _dbus_string_get_length (&signature));
00544             _dbus_verbose_bytes_of_string (&body, 0, _dbus_string_get_length (&body));
00545             _dbus_assert_not_reached ("test failed");
00546           }
00547 
00548         _dbus_string_set_length (&signature, 0);
00549         _dbus_string_set_length (&body, 0);
00550         ++sequence;
00551       }
00552                                                      
00553     sequence = 0;
00554     while (dbus_internal_do_not_use_generate_bodies (sequence,
00555                                                      DBUS_BIG_ENDIAN,
00556                                                      &signature, &body))
00557       {
00558         DBusValidity validity;
00559 
00560         validity = _dbus_validate_body_with_reason (&signature, 0,
00561                                                     DBUS_BIG_ENDIAN,
00562                                                     NULL, &body, 0,
00563                                                     _dbus_string_get_length (&body));
00564         if (validity != DBUS_VALID)
00565           {
00566             _dbus_warn ("invalid code %d expected valid on sequence %d big endian\n",
00567                         validity, sequence);
00568             _dbus_verbose_bytes_of_string (&signature, 0, _dbus_string_get_length (&signature));
00569             _dbus_verbose_bytes_of_string (&body, 0, _dbus_string_get_length (&body));
00570             _dbus_assert_not_reached ("test failed");
00571           }
00572 
00573         _dbus_string_set_length (&signature, 0);
00574         _dbus_string_set_length (&body, 0);
00575         ++sequence;
00576       }
00577 
00578     _dbus_string_free (&signature);
00579     _dbus_string_free (&body);
00580   }
00581   
00582   return TRUE;
00583 }
00584 
00585 #endif /* !DOXYGEN_SHOULD_SKIP_THIS */
00586 
00587 #endif /* DBUS_BUILD_TESTS */

Generated on Fri Sep 21 18:12:12 2007 for D-Bus by  doxygen 1.5.1