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