Main Page | Modules | Data Structures | Directories | File List | Data Fields | Related Pages

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

Generated on Wed Jan 3 04:49:04 2007 for D-BUS by  doxygen 1.4.4