1/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2/* dbus-marshal-validate-util.c Would be in dbus-marshal-validate.c, but only used by tests/bus 3 * 4 * Copyright (C) 2005 Red Hat, Inc. 5 * 6 * Licensed under the Academic Free License version 2.1 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24#include <config.h> 25#ifdef DBUS_BUILD_TESTS 26 27#ifndef DOXYGEN_SHOULD_SKIP_THIS 28 29#include "dbus-internals.h" 30#include "dbus-marshal-validate.h" 31#include "dbus-marshal-recursive.h" 32 33#include "dbus-test.h" 34#include <stdio.h> 35 36typedef struct 37{ 38 const char *data; 39 DBusValidity expected; 40} ValidityTest; 41 42static void 43run_validity_tests (const ValidityTest *tests, 44 int n_tests, 45 DBusValidity (* func) (const DBusString*,int,int)) 46{ 47 int i; 48 49 for (i = 0; i < n_tests; i++) 50 { 51 DBusString str; 52 DBusValidity v; 53 54 _dbus_string_init_const (&str, tests[i].data); 55 56 v = (*func) (&str, 0, _dbus_string_get_length (&str)); 57 58 if (v != tests[i].expected) 59 { 60 _dbus_warn ("Improper validation result %d for '%s'\n", 61 v, tests[i].data); 62 _dbus_assert_not_reached ("test failed"); 63 } 64 65 ++i; 66 } 67} 68 69static const ValidityTest signature_tests[] = { 70 { "", DBUS_VALID }, 71 { "i", DBUS_VALID }, 72 { "ai", DBUS_VALID }, 73 { "(i)", DBUS_VALID }, 74 { "w", DBUS_INVALID_UNKNOWN_TYPECODE }, 75 { "a", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE }, 76 { "aaaaaa", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE }, 77 { "ii(ii)a", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE }, 78 { "ia", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE }, 79 /* DBUS_INVALID_SIGNATURE_TOO_LONG, */ /* too hard to test this way */ 80 { "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", 81 DBUS_INVALID_EXCEEDED_MAXIMUM_ARRAY_RECURSION }, 82 { "((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((ii))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))))", 83 DBUS_INVALID_EXCEEDED_MAXIMUM_STRUCT_RECURSION }, 84 { ")", DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED }, 85 { "i)", DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED }, 86 { "a)", DBUS_INVALID_STRUCT_ENDED_BUT_NOT_STARTED }, 87 { "(", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED }, 88 { "(i", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED }, 89 { "(iiiii", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED }, 90 { "(ai", DBUS_INVALID_STRUCT_STARTED_BUT_NOT_ENDED }, 91 { "()", DBUS_INVALID_STRUCT_HAS_NO_FIELDS }, 92 { "(())", DBUS_INVALID_STRUCT_HAS_NO_FIELDS }, 93 { "a()", DBUS_INVALID_STRUCT_HAS_NO_FIELDS }, 94 { "i()", DBUS_INVALID_STRUCT_HAS_NO_FIELDS }, 95 { "()i", DBUS_INVALID_STRUCT_HAS_NO_FIELDS }, 96 { "(a)", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE }, 97 { "a{ia}", DBUS_INVALID_MISSING_ARRAY_ELEMENT_TYPE }, 98 { "a{}", DBUS_INVALID_DICT_ENTRY_HAS_NO_FIELDS }, 99 { "a{aii}", DBUS_INVALID_DICT_KEY_MUST_BE_BASIC_TYPE }, 100 /* { "a{i}", DBUS_INVALID_DICT_ENTRY_HAS_ONLY_ONE_FIELD }, */ 101 /* { "{is}", DBUS_INVALID_DICT_ENTRY_NOT_INSIDE_ARRAY }, */ 102 /* { "a{isi}", DBUS_INVALID_DICT_ENTRY_HAS_TOO_MANY_FIELDS }, */ 103}; 104 105dbus_bool_t 106_dbus_marshal_validate_test (void) 107{ 108 DBusString str; 109 int i; 110 111 const char *valid_paths[] = { 112 "/", 113 "/foo/bar", 114 "/foo", 115 "/foo/bar/baz" 116 }; 117 const char *invalid_paths[] = { 118 "bar", 119 "bar/baz", 120 "/foo/bar/", 121 "/foo/" 122 "foo/", 123 "boo//blah", 124 "//", 125 "///", 126 "foo///blah/", 127 "Hello World", 128 "", 129 " ", 130 "foo bar" 131 }; 132 133 const char *valid_interfaces[] = { 134 "org.freedesktop.Foo", 135 "Bar.Baz", 136 "Blah.Blah.Blah.Blah.Blah", 137 "a.b", 138 "a.b.c.d.e.f.g", 139 "a0.b1.c2.d3.e4.f5.g6", 140 "abc123.foo27" 141 }; 142 const char *invalid_interfaces[] = { 143 ".", 144 "", 145 "..", 146 ".Foo.Bar", 147 "..Foo.Bar", 148 "Foo.Bar.", 149 "Foo.Bar..", 150 "Foo", 151 "9foo.bar.baz", 152 "foo.bar..baz", 153 "foo.bar...baz", 154 "foo.bar.b..blah", 155 ":", 156 ":0-1", 157 "10", 158 ":11.34324", 159 "0.0.0", 160 "0..0", 161 "foo.Bar.%", 162 "foo.Bar!!", 163 "!Foo.bar.bz", 164 "foo.$.blah", 165 "", 166 " ", 167 "foo bar" 168 }; 169 170 const char *valid_unique_names[] = { 171 ":0", 172 ":a", 173 ":", 174 ":.a", 175 ":.1", 176 ":0.1", 177 ":000.2222", 178 ":.blah", 179 ":abce.freedesktop.blah" 180 }; 181 const char *invalid_unique_names[] = { 182 //":-", 183 ":!", 184 //":0-10", 185 ":blah.", 186 ":blah.", 187 ":blah..org", 188 ":blah.org..", 189 ":..blah.org", 190 "", 191 " ", 192 "foo bar" 193 }; 194 195 const char *valid_members[] = { 196 "Hello", 197 "Bar", 198 "foobar", 199 "_foobar", 200 "foo89" 201 }; 202 203 const char *invalid_members[] = { 204 "9Hello", 205 "10", 206 "1", 207 "foo-bar", 208 "blah.org", 209 ".blah", 210 "blah.", 211 "Hello.", 212 "!foo", 213 "", 214 " ", 215 "foo bar" 216 }; 217 218 const char *valid_signatures[] = { 219 "", 220 "sss", 221 "i", 222 "b" 223 }; 224 225 const char *invalid_signatures[] = { 226 " ", 227 "not a valid signature", 228 "123", 229 ".", 230 "(", 231 "a{(ii)i}" /* https://bugs.freedesktop.org/show_bug.cgi?id=17803 */ 232 }; 233 234 /* Signature with reason */ 235 236 run_validity_tests (signature_tests, _DBUS_N_ELEMENTS (signature_tests), 237 _dbus_validate_signature_with_reason); 238 239 /* Path validation */ 240 i = 0; 241 while (i < (int) _DBUS_N_ELEMENTS (valid_paths)) 242 { 243 _dbus_string_init_const (&str, valid_paths[i]); 244 245 if (!_dbus_validate_path (&str, 0, 246 _dbus_string_get_length (&str))) 247 { 248 _dbus_warn ("Path \"%s\" should have been valid\n", valid_paths[i]); 249 _dbus_assert_not_reached ("invalid path"); 250 } 251 252 ++i; 253 } 254 255 i = 0; 256 while (i < (int) _DBUS_N_ELEMENTS (invalid_paths)) 257 { 258 _dbus_string_init_const (&str, invalid_paths[i]); 259 260 if (_dbus_validate_path (&str, 0, 261 _dbus_string_get_length (&str))) 262 { 263 _dbus_warn ("Path \"%s\" should have been invalid\n", invalid_paths[i]); 264 _dbus_assert_not_reached ("valid path"); 265 } 266 267 ++i; 268 } 269 270 /* Interface validation */ 271 i = 0; 272 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces)) 273 { 274 _dbus_string_init_const (&str, valid_interfaces[i]); 275 276 if (!_dbus_validate_interface (&str, 0, 277 _dbus_string_get_length (&str))) 278 { 279 _dbus_warn ("Interface \"%s\" should have been valid\n", valid_interfaces[i]); 280 _dbus_assert_not_reached ("invalid interface"); 281 } 282 283 ++i; 284 } 285 286 i = 0; 287 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces)) 288 { 289 _dbus_string_init_const (&str, invalid_interfaces[i]); 290 291 if (_dbus_validate_interface (&str, 0, 292 _dbus_string_get_length (&str))) 293 { 294 _dbus_warn ("Interface \"%s\" should have been invalid\n", invalid_interfaces[i]); 295 _dbus_assert_not_reached ("valid interface"); 296 } 297 298 ++i; 299 } 300 301 /* Bus name validation (check that valid interfaces are valid bus names, 302 * and invalid interfaces are invalid services except if they start with ':') 303 */ 304 i = 0; 305 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces)) 306 { 307 _dbus_string_init_const (&str, valid_interfaces[i]); 308 309 if (!_dbus_validate_bus_name (&str, 0, 310 _dbus_string_get_length (&str))) 311 { 312 _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_interfaces[i]); 313 _dbus_assert_not_reached ("invalid bus name"); 314 } 315 316 ++i; 317 } 318 319 i = 0; 320 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces)) 321 { 322 if (invalid_interfaces[i][0] != ':') 323 { 324 _dbus_string_init_const (&str, invalid_interfaces[i]); 325 326 if (_dbus_validate_bus_name (&str, 0, 327 _dbus_string_get_length (&str))) 328 { 329 _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_interfaces[i]); 330 _dbus_assert_not_reached ("valid bus name"); 331 } 332 } 333 334 ++i; 335 } 336 337 /* unique name validation */ 338 i = 0; 339 while (i < (int) _DBUS_N_ELEMENTS (valid_unique_names)) 340 { 341 _dbus_string_init_const (&str, valid_unique_names[i]); 342 343 if (!_dbus_validate_bus_name (&str, 0, 344 _dbus_string_get_length (&str))) 345 { 346 _dbus_warn ("Bus name \"%s\" should have been valid\n", valid_unique_names[i]); 347 _dbus_assert_not_reached ("invalid unique name"); 348 } 349 350 ++i; 351 } 352 353 i = 0; 354 while (i < (int) _DBUS_N_ELEMENTS (invalid_unique_names)) 355 { 356 _dbus_string_init_const (&str, invalid_unique_names[i]); 357 358 if (_dbus_validate_bus_name (&str, 0, 359 _dbus_string_get_length (&str))) 360 { 361 _dbus_warn ("Bus name \"%s\" should have been invalid\n", invalid_unique_names[i]); 362 _dbus_assert_not_reached ("valid unique name"); 363 } 364 365 ++i; 366 } 367 368 369 /* Error name validation (currently identical to interfaces) 370 */ 371 i = 0; 372 while (i < (int) _DBUS_N_ELEMENTS (valid_interfaces)) 373 { 374 _dbus_string_init_const (&str, valid_interfaces[i]); 375 376 if (!_dbus_validate_error_name (&str, 0, 377 _dbus_string_get_length (&str))) 378 { 379 _dbus_warn ("Error name \"%s\" should have been valid\n", valid_interfaces[i]); 380 _dbus_assert_not_reached ("invalid error name"); 381 } 382 383 ++i; 384 } 385 386 i = 0; 387 while (i < (int) _DBUS_N_ELEMENTS (invalid_interfaces)) 388 { 389 if (invalid_interfaces[i][0] != ':') 390 { 391 _dbus_string_init_const (&str, invalid_interfaces[i]); 392 393 if (_dbus_validate_error_name (&str, 0, 394 _dbus_string_get_length (&str))) 395 { 396 _dbus_warn ("Error name \"%s\" should have been invalid\n", invalid_interfaces[i]); 397 _dbus_assert_not_reached ("valid error name"); 398 } 399 } 400 401 ++i; 402 } 403 404 /* Member validation */ 405 i = 0; 406 while (i < (int) _DBUS_N_ELEMENTS (valid_members)) 407 { 408 _dbus_string_init_const (&str, valid_members[i]); 409 410 if (!_dbus_validate_member (&str, 0, 411 _dbus_string_get_length (&str))) 412 { 413 _dbus_warn ("Member \"%s\" should have been valid\n", valid_members[i]); 414 _dbus_assert_not_reached ("invalid member"); 415 } 416 417 ++i; 418 } 419 420 i = 0; 421 while (i < (int) _DBUS_N_ELEMENTS (invalid_members)) 422 { 423 _dbus_string_init_const (&str, invalid_members[i]); 424 425 if (_dbus_validate_member (&str, 0, 426 _dbus_string_get_length (&str))) 427 { 428 _dbus_warn ("Member \"%s\" should have been invalid\n", invalid_members[i]); 429 _dbus_assert_not_reached ("valid member"); 430 } 431 432 ++i; 433 } 434 435 /* Signature validation */ 436 i = 0; 437 while (i < (int) _DBUS_N_ELEMENTS (valid_signatures)) 438 { 439 _dbus_string_init_const (&str, valid_signatures[i]); 440 441 if (!_dbus_validate_signature (&str, 0, 442 _dbus_string_get_length (&str))) 443 { 444 _dbus_warn ("Signature \"%s\" should have been valid\n", valid_signatures[i]); 445 _dbus_assert_not_reached ("invalid signature"); 446 } 447 448 ++i; 449 } 450 451 i = 0; 452 while (i < (int) _DBUS_N_ELEMENTS (invalid_signatures)) 453 { 454 _dbus_string_init_const (&str, invalid_signatures[i]); 455 456 if (_dbus_validate_signature (&str, 0, 457 _dbus_string_get_length (&str))) 458 { 459 _dbus_warn ("Signature \"%s\" should have been invalid\n", invalid_signatures[i]); 460 _dbus_assert_not_reached ("valid signature"); 461 } 462 463 ++i; 464 } 465 466 /* Validate claimed length longer than real length */ 467 _dbus_string_init_const (&str, "abc.efg"); 468 if (_dbus_validate_bus_name (&str, 0, 8)) 469 _dbus_assert_not_reached ("validated too-long string"); 470 if (_dbus_validate_interface (&str, 0, 8)) 471 _dbus_assert_not_reached ("validated too-long string"); 472 if (_dbus_validate_error_name (&str, 0, 8)) 473 _dbus_assert_not_reached ("validated too-long string"); 474 475 _dbus_string_init_const (&str, "abc"); 476 if (_dbus_validate_member (&str, 0, 4)) 477 _dbus_assert_not_reached ("validated too-long string"); 478 479 _dbus_string_init_const (&str, "sss"); 480 if (_dbus_validate_signature (&str, 0, 4)) 481 _dbus_assert_not_reached ("validated too-long signature"); 482 483 /* Validate string exceeding max name length */ 484 if (!_dbus_string_init (&str)) 485 _dbus_assert_not_reached ("no memory"); 486 487 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH) 488 if (!_dbus_string_append (&str, "abc.def")) 489 _dbus_assert_not_reached ("no memory"); 490 491 if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) 492 _dbus_assert_not_reached ("validated overmax string"); 493 if (_dbus_validate_interface (&str, 0, _dbus_string_get_length (&str))) 494 _dbus_assert_not_reached ("validated overmax string"); 495 if (_dbus_validate_error_name (&str, 0, _dbus_string_get_length (&str))) 496 _dbus_assert_not_reached ("validated overmax string"); 497 498 /* overlong member */ 499 _dbus_string_set_length (&str, 0); 500 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH) 501 if (!_dbus_string_append (&str, "abc")) 502 _dbus_assert_not_reached ("no memory"); 503 504 if (_dbus_validate_member (&str, 0, _dbus_string_get_length (&str))) 505 _dbus_assert_not_reached ("validated overmax string"); 506 507 /* overlong unique name */ 508 _dbus_string_set_length (&str, 0); 509 _dbus_string_append (&str, ":"); 510 while (_dbus_string_get_length (&str) <= DBUS_MAXIMUM_NAME_LENGTH) 511 if (!_dbus_string_append (&str, "abc")) 512 _dbus_assert_not_reached ("no memory"); 513 514 if (_dbus_validate_bus_name (&str, 0, _dbus_string_get_length (&str))) 515 _dbus_assert_not_reached ("validated overmax string"); 516 517 _dbus_string_free (&str); 518 519 /* Body validation; test basic validation of valid bodies for both endian */ 520 521 { 522 int sequence; 523 DBusString signature; 524 DBusString body; 525 526 if (!_dbus_string_init (&signature) || !_dbus_string_init (&body)) 527 _dbus_assert_not_reached ("oom"); 528 529 sequence = 0; 530 while (dbus_internal_do_not_use_generate_bodies (sequence, 531 DBUS_LITTLE_ENDIAN, 532 &signature, &body)) 533 { 534 DBusValidity validity; 535 536 validity = _dbus_validate_body_with_reason (&signature, 0, 537 DBUS_LITTLE_ENDIAN, 538 NULL, &body, 0, 539 _dbus_string_get_length (&body)); 540 if (validity != DBUS_VALID) 541 { 542 _dbus_warn ("invalid code %d expected valid on sequence %d little endian\n", 543 validity, sequence); 544 _dbus_verbose_bytes_of_string (&signature, 0, _dbus_string_get_length (&signature)); 545 _dbus_verbose_bytes_of_string (&body, 0, _dbus_string_get_length (&body)); 546 _dbus_assert_not_reached ("test failed"); 547 } 548 549 _dbus_string_set_length (&signature, 0); 550 _dbus_string_set_length (&body, 0); 551 ++sequence; 552 } 553 554 sequence = 0; 555 while (dbus_internal_do_not_use_generate_bodies (sequence, 556 DBUS_BIG_ENDIAN, 557 &signature, &body)) 558 { 559 DBusValidity validity; 560 561 validity = _dbus_validate_body_with_reason (&signature, 0, 562 DBUS_BIG_ENDIAN, 563 NULL, &body, 0, 564 _dbus_string_get_length (&body)); 565 if (validity != DBUS_VALID) 566 { 567 _dbus_warn ("invalid code %d expected valid on sequence %d big endian\n", 568 validity, sequence); 569 _dbus_verbose_bytes_of_string (&signature, 0, _dbus_string_get_length (&signature)); 570 _dbus_verbose_bytes_of_string (&body, 0, _dbus_string_get_length (&body)); 571 _dbus_assert_not_reached ("test failed"); 572 } 573 574 _dbus_string_set_length (&signature, 0); 575 _dbus_string_set_length (&body, 0); 576 ++sequence; 577 } 578 579 _dbus_string_free (&signature); 580 _dbus_string_free (&body); 581 } 582 583 return TRUE; 584} 585 586#endif /* !DOXYGEN_SHOULD_SKIP_THIS */ 587 588#endif /* DBUS_BUILD_TESTS */ 589