D-Bus 1.4.1
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 "a{(ii)i}" /* https://bugs.freedesktop.org/show_bug.cgi?id=17803 */ 00232 }; 00233 00234 /* Signature with reason */ 00235 00236 run_validity_tests (signature_tests, _DBUS_N_ELEMENTS (signature_tests), 00237 _dbus_validate_signature_with_reason); 00238 00239 /* Path validation */ 00240 i = 0; 00241 while (i < (int) _DBUS_N_ELEMENTS (valid_paths)) 00242 { 00243 _dbus_string_init_const (&str, valid_paths[i]); 00244 00245 if (!_dbus_validate_path (&str, 0, 00246 _dbus_string_get_length (&str))) 00247 { 00248 _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]); 00249 _dbus_assert_not_reached ("invalid path"); 00250 } 00251 00252 ++i; 00253 } 00254 00255 i = 0; 00256 while (i < (int) _DBUS_N_ELEMENTS (invalid_paths)) 00257 { 00258 _dbus_string_init_const (&str, invalid_paths[i]); 00259 00260 if (_dbus_validate_path (&str, 0, 00261 _dbus_string_get_length (&str))) 00262 { 00263 _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]); 00264 _dbus_assert_not_reached ("valid path"); 00265 } 00266 00267 ++i; 00268 } 00269 00270 /* Interface validation */ 00271 i = 0; 00272 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces)) 00273 { 00274 _dbus_string_init_const (&str, valid_interfaces[i]); 00275 00276 if (!_dbus_validate_interface (&str, 0, 00277 _dbus_string_get_length (&str))) 00278 { 00279 _dbus_warn ("Interface \"%s\" should have been valid\n", valid_interfaces[i]); 00280 _dbus_assert_not_reached ("invalid interface"); 00281 } 00282 00283 ++i; 00284 } 00285 00286 i = 0; 00287 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces)) 00288 { 00289 _dbus_string_init_const (&str, invalid_interfaces[i]); 00290 00291 if (_dbus_validate_interface (&str, 0, 00292 _dbus_string_get_length (&str))) 00293 { 00294 _dbus_warn ("Interface \"%s\" should have been invalid\n", invalid_interfaces[i]); 00295 _dbus_assert_not_reached ("valid interface"); 00296 } 00297 00298 ++i; 00299 } 00300 00301 /* Bus name validation (check that valid interfaces are valid bus names, 00302 * and invalid interfaces are invalid services except if they start with ':') 00303 */ 00304 i = 0; 00305 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces)) 00306 { 00307 _dbus_string_init_const (&str, valid_interfaces[i]); 00308 00309 if (!_dbus_validate_bus_name (&str, 0, 00310 _dbus_string_get_length (&str))) 00311 { 00312 _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_interfaces[i]); 00313 _dbus_assert_not_reached ("invalid bus name"); 00314 } 00315 00316 ++i; 00317 } 00318 00319 i = 0; 00320 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces)) 00321 { 00322 if (invalid_interfaces[i][0] != ':') 00323 { 00324 _dbus_string_init_const (&str, invalid_interfaces[i]); 00325 00326 if (_dbus_validate_bus_name (&str, 0, 00327 _dbus_string_get_length (&str))) 00328 { 00329 _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_interfaces[i]); 00330 _dbus_assert_not_reached ("valid bus name"); 00331 } 00332 } 00333 00334 ++i; 00335 } 00336 00337 /* unique name validation */ 00338 i = 0; 00339 while (i < (int) _DBUS_N_ELEMENTS (valid_unique_names)) 00340 { 00341 _dbus_string_init_const (&str, valid_unique_names[i]); 00342 00343 if (!_dbus_validate_bus_name (&str, 0, 00344 _dbus_string_get_length (&str))) 00345 { 00346 _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_unique_names[i]); 00347 _dbus_assert_not_reached ("invalid unique name"); 00348 } 00349 00350 ++i; 00351 } 00352 00353 i = 0; 00354 while (i < (int) _DBUS_N_ELEMENTS (invalid_unique_names)) 00355 { 00356 _dbus_string_init_const (&str, invalid_unique_names[i]); 00357 00358 if (_dbus_validate_bus_name (&str, 0, 00359 _dbus_string_get_length (&str))) 00360 { 00361 _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_unique_names[i]); 00362 _dbus_assert_not_reached ("valid unique name"); 00363 } 00364 00365 ++i; 00366 } 00367 00368 00369 /* Error name validation (currently identical to interfaces) 00370 */ 00371 i = 0; 00372 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces)) 00373 { 00374 _dbus_string_init_const (&str, valid_interfaces[i]); 00375 00376 if (!_dbus_validate_error_name (&str, 0, 00377 _dbus_string_get_length (&str))) 00378 { 00379 _dbus_warn ("Error name \"%s\" should have been valid\n", valid_interfaces[i]); 00380 _dbus_assert_not_reached ("invalid error name"); 00381 } 00382 00383 ++i; 00384 } 00385 00386 i = 0; 00387 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces)) 00388 { 00389 if (invalid_interfaces[i][0] != ':') 00390 { 00391 _dbus_string_init_const (&str, invalid_interfaces[i]); 00392 00393 if (_dbus_validate_error_name (&str, 0, 00394 _dbus_string_get_length (&str))) 00395 { 00396 _dbus_warn ("Error name \"%s\" should have been invalid\n", invalid_interfaces[i]); 00397 _dbus_assert_not_reached ("valid error name"); 00398 } 00399 } 00400 00401 ++i; 00402 } 00403 00404 /* Member validation */ 00405 i = 0; 00406 while (i < (int) _DBUS_N_ELEMENTS (valid_members)) 00407 { 00408 _dbus_string_init_const (&str, valid_members[i]); 00409 00410 if (!_dbus_validate_member (&str, 0, 00411 _dbus_string_get_length (&str))) 00412 { 00413 _dbus_warn ("Member \"%s\" should have been valid\n", valid_members[i]); 00414 _dbus_assert_not_reached ("invalid member"); 00415 } 00416 00417 ++i; 00418 } 00419 00420 i = 0; 00421 while (i < (int) _DBUS_N_ELEMENTS (invalid_members)) 00422 { 00423 _dbus_string_init_const (&str, invalid_members[i]); 00424 00425 if (_dbus_validate_member (&str, 0, 00426 _dbus_string_get_length (&str))) 00427 { 00428 _dbus_warn ("Member \"%s\" should have been invalid\n", invalid_members[i]); 00429 _dbus_assert_not_reached ("valid member"); 00430 } 00431 00432 ++i; 00433 } 00434 00435 /* Signature validation */ 00436 i = 0; 00437 while (i < (int) _DBUS_N_ELEMENTS (valid_signatures)) 00438 { 00439 _dbus_string_init_const (&str, valid_signatures[i]); 00440 00441 if (!_dbus_validate_signature (&str, 0, 00442 _dbus_string_get_length (&str))) 00443 { 00444 _dbus_warn ("Signature \"%s\" should have been valid\n", valid_signatures[i]); 00445 _dbus_assert_not_reached ("invalid signature"); 00446 } 00447 00448 ++i; 00449 } 00450 00451 i = 0; 00452 while (i < (int) _DBUS_N_ELEMENTS (invalid_signatures)) 00453 { 00454 _dbus_string_init_const (&str, invalid_signatures[i]); 00455 00456 if (_dbus_validate_signature (&str, 0, 00457 _dbus_string_get_length (&str))) 00458 { 00459 _dbus_warn ("Signature \"%s\" should have been invalid\n", invalid_signatures[i]); 00460 _dbus_assert_not_reached ("valid signature"); 00461 } 00462 00463 ++i; 00464 } 00465 00466 /* Validate claimed length longer than real length */ 00467 _dbus_string_init_const (&str, "abc.efg"); 00468 if (_dbus_validate_bus_name (&str, 0, 8)) 00469 _dbus_assert_not_reached ("validated too-long string"); 00470 if (_dbus_validate_interface (&str, 0, 8)) 00471 _dbus_assert_not_reached ("validated too-long string"); 00472 if (_dbus_validate_error_name (&str, 0, 8)) 00473 _dbus_assert_not_reached ("validated too-long string"); 00474 00475 _dbus_string_init_const (&str, "abc"); 00476 if (_dbus_validate_member (&str, 0, 4)) 00477 _dbus_assert_not_reached ("validated too-long string"); 00478 00479 _dbus_string_init_const (&str, "sss"); 00480 if (_dbus_validate_signature (&str, 0, 4)) 00481 _dbus_assert_not_reached ("validated too-long signature"); 00482 00483 /* Validate string exceeding max name length */ 00484 if (!_dbus_string_init (&str)) 00485 _dbus_assert_not_reached ("no memory"); 00486 00487 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH) 00488 if (!_dbus_string_append (&str, "abc.def")) 00489 _dbus_assert_not_reached ("no memory"); 00490 00491 if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) 00492 _dbus_assert_not_reached ("validated overmax string"); 00493 if (_dbus_validate_interface (&str, 0, _dbus_string_get_length (&str))) 00494 _dbus_assert_not_reached ("validated overmax string"); 00495 if (_dbus_validate_error_name (&str, 0, _dbus_string_get_length (&str))) 00496 _dbus_assert_not_reached ("validated overmax string"); 00497 00498 /* overlong member */ 00499 _dbus_string_set_length (&str, 0); 00500 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH) 00501 if (!_dbus_string_append (&str, "abc")) 00502 _dbus_assert_not_reached ("no memory"); 00503 00504 if (_dbus_validate_member (&str, 0, _dbus_string_get_length (&str))) 00505 _dbus_assert_not_reached ("validated overmax string"); 00506 00507 /* overlong unique name */ 00508 _dbus_string_set_length (&str, 0); 00509 _dbus_string_append (&str, ":"); 00510 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH) 00511 if (!_dbus_string_append (&str, "abc")) 00512 _dbus_assert_not_reached ("no memory"); 00513 00514 if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) 00515 _dbus_assert_not_reached ("validated overmax string"); 00516 00517 _dbus_string_free (&str); 00518 00519 /* Body validation; test basic validation of valid bodies for both endian */ 00520 00521 { 00522 int sequence; 00523 DBusString signature; 00524 DBusString body; 00525 00526 if (!_dbus_string_init (&signature) || !_dbus_string_init (&body)) 00527 _dbus_assert_not_reached ("oom"); 00528 00529 sequence = 0; 00530 while (dbus_internal_do_not_use_generate_bodies (sequence, 00531 DBUS_LITTLE_ENDIAN, 00532 &signature, &body)) 00533 { 00534 DBusValidity validity; 00535 00536 validity = _dbus_validate_body_with_reason (&signature, 0, 00537 DBUS_LITTLE_ENDIAN, 00538 NULL, &body, 0, 00539 _dbus_string_get_length (&body)); 00540 if (validity != DBUS_VALID) 00541 { 00542 _dbus_warn ("invalid code %d expected valid on sequence %d little endian\n", 00543 validity, sequence); 00544 _dbus_verbose_bytes_of_string (&signature, 0, _dbus_string_get_length (&signature)); 00545 _dbus_verbose_bytes_of_string (&body, 0, _dbus_string_get_length (&body)); 00546 _dbus_assert_not_reached ("test failed"); 00547 } 00548 00549 _dbus_string_set_length (&signature, 0); 00550 _dbus_string_set_length (&body, 0); 00551 ++sequence; 00552 } 00553 00554 sequence = 0; 00555 while (dbus_internal_do_not_use_generate_bodies (sequence, 00556 DBUS_BIG_ENDIAN, 00557 &signature, &body)) 00558 { 00559 DBusValidity validity; 00560 00561 validity = _dbus_validate_body_with_reason (&signature, 0, 00562 DBUS_BIG_ENDIAN, 00563 NULL, &body, 0, 00564 _dbus_string_get_length (&body)); 00565 if (validity != DBUS_VALID) 00566 { 00567 _dbus_warn ("invalid code %d expected valid on sequence %d big endian\n", 00568 validity, sequence); 00569 _dbus_verbose_bytes_of_string (&signature, 0, _dbus_string_get_length (&signature)); 00570 _dbus_verbose_bytes_of_string (&body, 0, _dbus_string_get_length (&body)); 00571 _dbus_assert_not_reached ("test failed"); 00572 } 00573 00574 _dbus_string_set_length (&signature, 0); 00575 _dbus_string_set_length (&body, 0); 00576 ++sequence; 00577 } 00578 00579 _dbus_string_free (&signature); 00580 _dbus_string_free (&body); 00581 } 00582 00583 return TRUE; 00584 } 00585 00586 #endif /* !DOXYGEN_SHOULD_SKIP_THIS */ 00587 00588 #endif /* DBUS_BUILD_TESTS */