1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* dbus-message-util.c Would be in dbus-message.c, but only used by bus/tests 3 * 4 * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc. 5 * Copyright (C) 2002, 2003 CodeFactory AB 6 * 7 * Licensed under the Academic Free License version 2.1 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #include <config.h> 26 #include "dbus-internals.h" 27 #include "dbus-test.h" 28 #include "dbus-message-private.h" 29 #include "dbus-marshal-recursive.h" 30 #include "dbus-string.h" 31 #ifdef HAVE_UNIX_FD_PASSING 32 #include "dbus-sysdeps-unix.h" 33 #endif 34 35 #ifdef __linux__ 36 /* Necessary for the Linux-specific fd leak checking code only */ 37 #include <sys/types.h> 38 #include <dirent.h> 39 #include <stdlib.h> 40 #include <errno.h> 41 #endif 42 43 /** 44 * @addtogroup DBusMessage 45 * @{ 46 */ 47 48 #ifdef DBUS_BUILD_TESTS 49 /** 50 * Reads arguments from a message iterator given a variable argument 51 * list. Only arguments of basic type and arrays of fixed-length 52 * basic type may be read with this function. See 53 * dbus_message_get_args() for more details. 54 * 55 * @param iter the message iterator 56 * @param error error to be filled in on failure 57 * @param first_arg_type the first argument type 58 * @param ... location for first argument value, then list of type-location pairs 59 * @returns #FALSE if the error was set 60 */ 61 static dbus_bool_t 62 dbus_message_iter_get_args (DBusMessageIter *iter, 63 DBusError *error, 64 int first_arg_type, 65 ...) 66 { 67 dbus_bool_t retval; 68 va_list var_args; 69 70 _dbus_return_val_if_fail (iter != NULL, FALSE); 71 _dbus_return_val_if_error_is_set (error, FALSE); 72 73 va_start (var_args, first_arg_type); 74 retval = _dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args); 75 va_end (var_args); 76 77 return retval; 78 } 79 #endif /* DBUS_BUILD_TESTS */ 80 81 /** @} */ 82 83 #ifdef DBUS_BUILD_TESTS 84 #include "dbus-test.h" 85 #include "dbus-message-factory.h" 86 #include <stdio.h> 87 #include <stdlib.h> 88 89 static int validities_seen[DBUS_VALIDITY_LAST + _DBUS_NEGATIVE_VALIDITY_COUNT]; 90 91 static void 92 reset_validities_seen (void) 93 { 94 int i; 95 i = 0; 96 while (i < _DBUS_N_ELEMENTS (validities_seen)) 97 { 98 validities_seen[i] = 0; 99 ++i; 100 } 101 } 102 103 static void 104 record_validity_seen (DBusValidity validity) 105 { 106 validities_seen[validity + _DBUS_NEGATIVE_VALIDITY_COUNT] += 1; 107 } 108 109 static void 110 print_validities_seen (dbus_bool_t not_seen) 111 { 112 int i; 113 i = 0; 114 while (i < _DBUS_N_ELEMENTS (validities_seen)) 115 { 116 if ((i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_VALIDITY_UNKNOWN || 117 (i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_INVALID_FOR_UNKNOWN_REASON) 118 ; 119 else if ((not_seen && validities_seen[i] == 0) || 120 (!not_seen && validities_seen[i] > 0)) 121 printf ("validity %3d seen %d times\n", 122 i - _DBUS_NEGATIVE_VALIDITY_COUNT, 123 validities_seen[i]); 124 ++i; 125 } 126 } 127 128 static void 129 check_memleaks (void) 130 { 131 dbus_shutdown (); 132 133 if (_dbus_get_malloc_blocks_outstanding () != 0) 134 { 135 _dbus_warn ("%d dbus_malloc blocks were not freed in %s\n", 136 _dbus_get_malloc_blocks_outstanding (), __FILE__); 137 _dbus_assert_not_reached ("memleaks"); 138 } 139 } 140 141 void 142 _dbus_check_fdleaks(void) 143 { 144 145 #ifdef __linux__ 146 147 DIR *d; 148 149 /* This works on Linux only */ 150 151 if ((d = opendir("/proc/self/fd"))) 152 { 153 struct dirent *de; 154 155 while ((de = readdir(d))) 156 { 157 long l; 158 char *e = NULL; 159 int fd; 160 161 if (de->d_name[0] == '.') 162 continue; 163 164 errno = 0; 165 l = strtol(de->d_name, &e, 10); 166 _dbus_assert(errno == 0 && e && !*e); 167 168 fd = (int) l; 169 170 if (fd < 3) 171 continue; 172 173 if (fd == dirfd(d)) 174 continue; 175 176 _dbus_warn("file descriptor %i leaked in %s.\n", fd, __FILE__); 177 _dbus_assert_not_reached("fdleaks"); 178 } 179 180 closedir(d); 181 } 182 #endif 183 } 184 185 static dbus_bool_t 186 check_have_valid_message (DBusMessageLoader *loader) 187 { 188 DBusMessage *message; 189 dbus_bool_t retval; 190 191 message = NULL; 192 retval = FALSE; 193 194 if (_dbus_message_loader_get_is_corrupted (loader)) 195 { 196 _dbus_warn ("loader corrupted on message that was expected to be valid; invalid reason %d\n", 197 loader->corruption_reason); 198 goto failed; 199 } 200 201 message = _dbus_message_loader_pop_message (loader); 202 if (message == NULL) 203 { 204 _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n"); 205 goto failed; 206 } 207 208 if (_dbus_string_get_length (&loader->data) > 0) 209 { 210 _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n"); 211 goto failed; 212 } 213 214 #if 0 215 /* FIXME */ 216 /* Verify that we're able to properly deal with the message. 217 * For example, this would detect improper handling of messages 218 * in nonstandard byte order. 219 */ 220 if (!check_message_handling (message)) 221 goto failed; 222 #endif 223 224 record_validity_seen (DBUS_VALID); 225 226 retval = TRUE; 227 228 failed: 229 if (message) 230 dbus_message_unref (message); 231 232 return retval; 233 } 234 235 static dbus_bool_t 236 check_invalid_message (DBusMessageLoader *loader, 237 DBusValidity expected_validity) 238 { 239 dbus_bool_t retval; 240 241 retval = FALSE; 242 243 if (!_dbus_message_loader_get_is_corrupted (loader)) 244 { 245 _dbus_warn ("loader not corrupted on message that was expected to be invalid\n"); 246 goto failed; 247 } 248 249 record_validity_seen (loader->corruption_reason); 250 251 if (expected_validity != DBUS_INVALID_FOR_UNKNOWN_REASON && 252 loader->corruption_reason != expected_validity) 253 { 254 _dbus_warn ("expected message to be corrupted for reason %d and was corrupted for %d instead\n", 255 expected_validity, loader->corruption_reason); 256 goto failed; 257 } 258 259 retval = TRUE; 260 261 failed: 262 return retval; 263 } 264 265 static dbus_bool_t 266 check_incomplete_message (DBusMessageLoader *loader) 267 { 268 DBusMessage *message; 269 dbus_bool_t retval; 270 271 message = NULL; 272 retval = FALSE; 273 274 if (_dbus_message_loader_get_is_corrupted (loader)) 275 { 276 _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete), corruption reason %d\n", 277 loader->corruption_reason); 278 goto failed; 279 } 280 281 message = _dbus_message_loader_pop_message (loader); 282 if (message != NULL) 283 { 284 _dbus_warn ("loaded message that was expected to be incomplete\n"); 285 goto failed; 286 } 287 288 record_validity_seen (DBUS_VALID_BUT_INCOMPLETE); 289 retval = TRUE; 290 291 failed: 292 if (message) 293 dbus_message_unref (message); 294 return retval; 295 } 296 297 static dbus_bool_t 298 check_loader_results (DBusMessageLoader *loader, 299 DBusValidity expected_validity) 300 { 301 if (!_dbus_message_loader_queue_messages (loader)) 302 _dbus_assert_not_reached ("no memory to queue messages"); 303 304 if (expected_validity == DBUS_VALID) 305 return check_have_valid_message (loader); 306 else if (expected_validity == DBUS_VALID_BUT_INCOMPLETE) 307 return check_incomplete_message (loader); 308 else if (expected_validity == DBUS_VALIDITY_UNKNOWN) 309 { 310 /* here we just know we didn't segfault and that was the 311 * only test. Also, we record that we got coverage 312 * for the validity reason. 313 */ 314 if (_dbus_message_loader_get_is_corrupted (loader)) 315 record_validity_seen (loader->corruption_reason); 316 317 return TRUE; 318 } 319 else 320 return check_invalid_message (loader, expected_validity); 321 } 322 323 /** 324 * Loads the message in the given message file. 325 * 326 * @param filename filename to load 327 * @param data string to load message into 328 * @returns #TRUE if the message was loaded 329 */ 330 dbus_bool_t 331 dbus_internal_do_not_use_load_message_file (const DBusString *filename, 332 DBusString *data) 333 { 334 dbus_bool_t retval; 335 DBusError error = DBUS_ERROR_INIT; 336 337 retval = FALSE; 338 339 _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename)); 340 if (!_dbus_file_get_contents (data, filename, &error)) 341 { 342 _dbus_warn ("Could not load message file %s: %s\n", 343 _dbus_string_get_const_data (filename), 344 error.message); 345 dbus_error_free (&error); 346 goto failed; 347 } 348 349 retval = TRUE; 350 351 failed: 352 353 return retval; 354 } 355 356 /** 357 * Tries loading the message in the given message file 358 * and verifies that DBusMessageLoader can handle it. 359 * 360 * @param filename filename to load 361 * @param expected_validity what the message has to be like to return #TRUE 362 * @returns #TRUE if the message has the expected validity 363 */ 364 dbus_bool_t 365 dbus_internal_do_not_use_try_message_file (const DBusString *filename, 366 DBusValidity expected_validity) 367 { 368 DBusString data; 369 dbus_bool_t retval; 370 371 retval = FALSE; 372 373 if (!_dbus_string_init (&data)) 374 _dbus_assert_not_reached ("could not allocate string\n"); 375 376 if (!dbus_internal_do_not_use_load_message_file (filename, &data)) 377 goto failed; 378 379 retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity); 380 381 failed: 382 383 if (!retval) 384 { 385 if (_dbus_string_get_length (&data) > 0) 386 _dbus_verbose_bytes_of_string (&data, 0, 387 _dbus_string_get_length (&data)); 388 389 _dbus_warn ("Failed message loader test on %s\n", 390 _dbus_string_get_const_data (filename)); 391 } 392 393 _dbus_string_free (&data); 394 395 return retval; 396 } 397 398 /** 399 * Tries loading the given message data. 400 * 401 * 402 * @param data the message data 403 * @param expected_validity what the message has to be like to return #TRUE 404 * @returns #TRUE if the message has the expected validity 405 */ 406 dbus_bool_t 407 dbus_internal_do_not_use_try_message_data (const DBusString *data, 408 DBusValidity expected_validity) 409 { 410 DBusMessageLoader *loader; 411 dbus_bool_t retval; 412 int len; 413 int i; 414 415 loader = NULL; 416 retval = FALSE; 417 418 /* Write the data one byte at a time */ 419 420 loader = _dbus_message_loader_new (); 421 422 /* check some trivial loader functions */ 423 _dbus_message_loader_ref (loader); 424 _dbus_message_loader_unref (loader); 425 _dbus_message_loader_get_max_message_size (loader); 426 427 len = _dbus_string_get_length (data); 428 for (i = 0; i < len; i++) 429 { 430 DBusString *buffer; 431 432 _dbus_message_loader_get_buffer (loader, &buffer); 433 _dbus_string_append_byte (buffer, 434 _dbus_string_get_byte (data, i)); 435 _dbus_message_loader_return_buffer (loader, buffer, 1); 436 } 437 438 if (!check_loader_results (loader, expected_validity)) 439 goto failed; 440 441 _dbus_message_loader_unref (loader); 442 loader = NULL; 443 444 /* Write the data all at once */ 445 446 loader = _dbus_message_loader_new (); 447 448 { 449 DBusString *buffer; 450 451 _dbus_message_loader_get_buffer (loader, &buffer); 452 _dbus_string_copy (data, 0, buffer, 453 _dbus_string_get_length (buffer)); 454 _dbus_message_loader_return_buffer (loader, buffer, 1); 455 } 456 457 if (!check_loader_results (loader, expected_validity)) 458 goto failed; 459 460 _dbus_message_loader_unref (loader); 461 loader = NULL; 462 463 /* Write the data 2 bytes at a time */ 464 465 loader = _dbus_message_loader_new (); 466 467 len = _dbus_string_get_length (data); 468 for (i = 0; i < len; i += 2) 469 { 470 DBusString *buffer; 471 472 _dbus_message_loader_get_buffer (loader, &buffer); 473 _dbus_string_append_byte (buffer, 474 _dbus_string_get_byte (data, i)); 475 if ((i+1) < len) 476 _dbus_string_append_byte (buffer, 477 _dbus_string_get_byte (data, i+1)); 478 _dbus_message_loader_return_buffer (loader, buffer, 1); 479 } 480 481 if (!check_loader_results (loader, expected_validity)) 482 goto failed; 483 484 _dbus_message_loader_unref (loader); 485 loader = NULL; 486 487 retval = TRUE; 488 489 failed: 490 491 if (loader) 492 _dbus_message_loader_unref (loader); 493 494 return retval; 495 } 496 497 static dbus_bool_t 498 process_test_subdir (const DBusString *test_base_dir, 499 const char *subdir, 500 DBusValidity expected_validity, 501 DBusForeachMessageFileFunc function, 502 void *user_data) 503 { 504 DBusString test_directory; 505 DBusString filename; 506 DBusDirIter *dir; 507 dbus_bool_t retval; 508 DBusError error = DBUS_ERROR_INIT; 509 510 retval = FALSE; 511 dir = NULL; 512 513 if (!_dbus_string_init (&test_directory)) 514 _dbus_assert_not_reached ("didn't allocate test_directory\n"); 515 516 _dbus_string_init_const (&filename, subdir); 517 518 if (!_dbus_string_copy (test_base_dir, 0, 519 &test_directory, 0)) 520 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory"); 521 522 if (!_dbus_concat_dir_and_file (&test_directory, &filename)) 523 _dbus_assert_not_reached ("couldn't allocate full path"); 524 525 _dbus_string_free (&filename); 526 if (!_dbus_string_init (&filename)) 527 _dbus_assert_not_reached ("didn't allocate filename string\n"); 528 529 dir = _dbus_directory_open (&test_directory, &error); 530 if (dir == NULL) 531 { 532 _dbus_warn ("Could not open %s: %s\n", 533 _dbus_string_get_const_data (&test_directory), 534 error.message); 535 dbus_error_free (&error); 536 goto failed; 537 } 538 539 printf ("Testing %s:\n", subdir); 540 541 next: 542 while (_dbus_directory_get_next_file (dir, &filename, &error)) 543 { 544 DBusString full_path; 545 546 if (!_dbus_string_init (&full_path)) 547 _dbus_assert_not_reached ("couldn't init string"); 548 549 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0)) 550 _dbus_assert_not_reached ("couldn't copy dir to full_path"); 551 552 if (!_dbus_concat_dir_and_file (&full_path, &filename)) 553 _dbus_assert_not_reached ("couldn't concat file to dir"); 554 555 if (_dbus_string_ends_with_c_str (&filename, ".message-raw")) 556 ; 557 else 558 { 559 if (_dbus_string_ends_with_c_str (&filename, ".message")) 560 { 561 _dbus_warn ("Could not load %s, message builder language no longer supported\n", 562 _dbus_string_get_const_data (&filename)); 563 } 564 565 _dbus_verbose ("Skipping non-.message file %s\n", 566 _dbus_string_get_const_data (&filename)); 567 _dbus_string_free (&full_path); 568 goto next; 569 } 570 571 printf (" %s\n", 572 _dbus_string_get_const_data (&filename)); 573 574 if (! (*function) (&full_path, 575 expected_validity, user_data)) 576 { 577 _dbus_string_free (&full_path); 578 goto failed; 579 } 580 else 581 _dbus_string_free (&full_path); 582 } 583 584 if (dbus_error_is_set (&error)) 585 { 586 _dbus_warn ("Could not get next file in %s: %s\n", 587 _dbus_string_get_const_data (&test_directory), 588 error.message); 589 dbus_error_free (&error); 590 goto failed; 591 } 592 593 retval = TRUE; 594 595 failed: 596 597 if (dir) 598 _dbus_directory_close (dir); 599 _dbus_string_free (&test_directory); 600 _dbus_string_free (&filename); 601 602 return retval; 603 } 604 605 /** 606 * Runs the given function on every message file in the test suite. 607 * The function should return #FALSE on test failure or fatal error. 608 * 609 * @param test_data_dir root dir of the test suite data files (top_srcdir/test/data) 610 * @param func the function to run 611 * @param user_data data for function 612 * @returns #FALSE if there's a failure 613 */ 614 dbus_bool_t 615 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir, 616 DBusForeachMessageFileFunc func, 617 void *user_data) 618 { 619 DBusString test_directory; 620 dbus_bool_t retval; 621 622 retval = FALSE; 623 624 _dbus_string_init_const (&test_directory, test_data_dir); 625 626 if (!process_test_subdir (&test_directory, "valid-messages", 627 DBUS_VALID, func, user_data)) 628 goto failed; 629 630 check_memleaks (); 631 632 if (!process_test_subdir (&test_directory, "invalid-messages", 633 DBUS_INVALID_FOR_UNKNOWN_REASON, func, user_data)) 634 goto failed; 635 636 check_memleaks (); 637 638 if (!process_test_subdir (&test_directory, "incomplete-messages", 639 DBUS_VALID_BUT_INCOMPLETE, func, user_data)) 640 goto failed; 641 642 check_memleaks (); 643 644 retval = TRUE; 645 646 failed: 647 648 _dbus_string_free (&test_directory); 649 650 return retval; 651 } 652 653 #if 0 654 #define GET_AND_CHECK(iter, typename, literal) \ 655 do { \ 656 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \ 657 _dbus_assert_not_reached ("got wrong argument type from message iter"); \ 658 dbus_message_iter_get_basic (&iter, &v_##typename); \ 659 if (v_##typename != literal) \ 660 _dbus_assert_not_reached ("got wrong value from message iter"); \ 661 } while (0) 662 663 #define GET_AND_CHECK_STRCMP(iter, typename, literal) \ 664 do { \ 665 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \ 666 _dbus_assert_not_reached ("got wrong argument type from message iter"); \ 667 dbus_message_iter_get_basic (&iter, &v_##typename); \ 668 if (strcmp (v_##typename, literal) != 0) \ 669 _dbus_assert_not_reached ("got wrong value from message iter"); \ 670 } while (0) 671 672 #define GET_AND_CHECK_AND_NEXT(iter, typename, literal) \ 673 do { \ 674 GET_AND_CHECK(iter, typename, literal); \ 675 if (!dbus_message_iter_next (&iter)) \ 676 _dbus_assert_not_reached ("failed to move iter to next"); \ 677 } while (0) 678 679 #define GET_AND_CHECK_STRCMP_AND_NEXT(iter, typename, literal) \ 680 do { \ 681 GET_AND_CHECK_STRCMP(iter, typename, literal); \ 682 if (!dbus_message_iter_next (&iter)) \ 683 _dbus_assert_not_reached ("failed to move iter to next"); \ 684 } while (0) 685 686 static void 687 message_iter_test (DBusMessage *message) 688 { 689 DBusMessageIter iter, array, array2; 690 const char *v_STRING; 691 double v_DOUBLE; 692 dbus_int16_t v_INT16; 693 dbus_uint16_t v_UINT16; 694 dbus_int32_t v_INT32; 695 dbus_uint32_t v_UINT32; 696 #ifdef DBUS_HAVE_INT64 697 dbus_int64_t v_INT64; 698 dbus_uint64_t v_UINT64; 699 #endif 700 unsigned char v_BYTE; 701 dbus_bool_t v_BOOLEAN; 702 703 const dbus_int32_t *our_int_array; 704 int len; 705 706 dbus_message_iter_init (message, &iter); 707 708 GET_AND_CHECK_STRCMP_AND_NEXT (iter, STRING, "Test string"); 709 GET_AND_CHECK_AND_NEXT (iter, INT32, -0x12345678); 710 GET_AND_CHECK_AND_NEXT (iter, UINT32, 0xedd1e); 711 GET_AND_CHECK_AND_NEXT (iter, DOUBLE, 3.14159); 712 713 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) 714 _dbus_assert_not_reached ("Argument type not an array"); 715 716 if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_DOUBLE) 717 _dbus_assert_not_reached ("Array type not double"); 718 719 dbus_message_iter_recurse (&iter, &array); 720 721 GET_AND_CHECK_AND_NEXT (array, DOUBLE, 1.5); 722 GET_AND_CHECK (array, DOUBLE, 2.5); 723 724 if (dbus_message_iter_next (&array)) 725 _dbus_assert_not_reached ("Didn't reach end of array"); 726 727 if (!dbus_message_iter_next (&iter)) 728 _dbus_assert_not_reached ("Reached end of arguments"); 729 730 GET_AND_CHECK_AND_NEXT (iter, BYTE, 0xF0); 731 732 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) 733 _dbus_assert_not_reached ("no array"); 734 735 if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_INT32) 736 _dbus_assert_not_reached ("Array type not int32"); 737 738 /* Empty array */ 739 dbus_message_iter_recurse (&iter, &array); 740 741 if (dbus_message_iter_next (&array)) 742 _dbus_assert_not_reached ("Didn't reach end of array"); 743 744 if (!dbus_message_iter_next (&iter)) 745 _dbus_assert_not_reached ("Reached end of arguments"); 746 747 GET_AND_CHECK (iter, BYTE, 0xF0); 748 749 if (dbus_message_iter_next (&iter)) 750 _dbus_assert_not_reached ("Didn't reach end of arguments"); 751 } 752 #endif 753 754 static void 755 verify_test_message (DBusMessage *message) 756 { 757 DBusMessageIter iter; 758 DBusError error = DBUS_ERROR_INIT; 759 dbus_int16_t our_int16; 760 dbus_uint16_t our_uint16; 761 dbus_int32_t our_int; 762 dbus_uint32_t our_uint; 763 const char *our_str; 764 double our_double; 765 double v_DOUBLE; 766 dbus_bool_t our_bool; 767 unsigned char our_byte_1, our_byte_2; 768 const dbus_uint32_t *our_uint32_array = (void*)0xdeadbeef; 769 int our_uint32_array_len; 770 dbus_int32_t *our_int32_array = (void*)0xdeadbeef; 771 int our_int32_array_len; 772 #ifdef DBUS_HAVE_INT64 773 dbus_int64_t our_int64; 774 dbus_uint64_t our_uint64; 775 dbus_int64_t *our_uint64_array = (void*)0xdeadbeef; 776 int our_uint64_array_len; 777 const dbus_int64_t *our_int64_array = (void*)0xdeadbeef; 778 int our_int64_array_len; 779 #endif 780 const double *our_double_array = (void*)0xdeadbeef; 781 int our_double_array_len; 782 const unsigned char *our_byte_array = (void*)0xdeadbeef; 783 int our_byte_array_len; 784 const dbus_bool_t *our_boolean_array = (void*)0xdeadbeef; 785 int our_boolean_array_len; 786 char **our_string_array; 787 int our_string_array_len; 788 789 dbus_message_iter_init (message, &iter); 790 791 if (!dbus_message_iter_get_args (&iter, &error, 792 DBUS_TYPE_INT16, &our_int16, 793 DBUS_TYPE_UINT16, &our_uint16, 794 DBUS_TYPE_INT32, &our_int, 795 DBUS_TYPE_UINT32, &our_uint, 796 #ifdef DBUS_HAVE_INT64 797 DBUS_TYPE_INT64, &our_int64, 798 DBUS_TYPE_UINT64, &our_uint64, 799 #endif 800 DBUS_TYPE_STRING, &our_str, 801 DBUS_TYPE_DOUBLE, &our_double, 802 DBUS_TYPE_BOOLEAN, &our_bool, 803 DBUS_TYPE_BYTE, &our_byte_1, 804 DBUS_TYPE_BYTE, &our_byte_2, 805 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 806 &our_uint32_array, &our_uint32_array_len, 807 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, 808 &our_int32_array, &our_int32_array_len, 809 #ifdef DBUS_HAVE_INT64 810 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, 811 &our_uint64_array, &our_uint64_array_len, 812 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, 813 &our_int64_array, &our_int64_array_len, 814 #endif 815 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, 816 &our_double_array, &our_double_array_len, 817 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, 818 &our_byte_array, &our_byte_array_len, 819 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, 820 &our_boolean_array, &our_boolean_array_len, 821 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 822 &our_string_array, &our_string_array_len, 823 0)) 824 { 825 _dbus_warn ("error: %s - %s\n", error.name, 826 (error.message != NULL) ? error.message : "no message"); 827 _dbus_assert_not_reached ("Could not get arguments"); 828 } 829 830 if (our_int16 != -0x123) 831 _dbus_assert_not_reached ("16-bit integers differ!"); 832 833 if (our_uint16 != 0x123) 834 _dbus_assert_not_reached ("16-bit uints differ!"); 835 836 if (our_int != -0x12345678) 837 _dbus_assert_not_reached ("integers differ!"); 838 839 if (our_uint != 0x12300042) 840 _dbus_assert_not_reached ("uints differ!"); 841 842 #ifdef DBUS_HAVE_INT64 843 if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd)) 844 _dbus_assert_not_reached ("64-bit integers differ!"); 845 if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd)) 846 _dbus_assert_not_reached ("64-bit unsigned integers differ!"); 847 #endif 848 849 v_DOUBLE = 3.14159; 850 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double, v_DOUBLE)) 851 _dbus_assert_not_reached ("doubles differ!"); 852 853 if (strcmp (our_str, "Test string") != 0) 854 _dbus_assert_not_reached ("strings differ!"); 855 856 if (!our_bool) 857 _dbus_assert_not_reached ("booleans differ"); 858 859 if (our_byte_1 != 42) 860 _dbus_assert_not_reached ("bytes differ!"); 861 862 if (our_byte_2 != 24) 863 _dbus_assert_not_reached ("bytes differ!"); 864 865 if (our_uint32_array_len != 4 || 866 our_uint32_array[0] != 0x12345678 || 867 our_uint32_array[1] != 0x23456781 || 868 our_uint32_array[2] != 0x34567812 || 869 our_uint32_array[3] != 0x45678123) 870 _dbus_assert_not_reached ("uint array differs"); 871 872 if (our_int32_array_len != 4 || 873 our_int32_array[0] != 0x12345678 || 874 our_int32_array[1] != -0x23456781 || 875 our_int32_array[2] != 0x34567812 || 876 our_int32_array[3] != -0x45678123) 877 _dbus_assert_not_reached ("int array differs"); 878 879 #ifdef DBUS_HAVE_INT64 880 if (our_uint64_array_len != 4 || 881 our_uint64_array[0] != 0x12345678 || 882 our_uint64_array[1] != 0x23456781 || 883 our_uint64_array[2] != 0x34567812 || 884 our_uint64_array[3] != 0x45678123) 885 _dbus_assert_not_reached ("uint64 array differs"); 886 887 if (our_int64_array_len != 4 || 888 our_int64_array[0] != 0x12345678 || 889 our_int64_array[1] != -0x23456781 || 890 our_int64_array[2] != 0x34567812 || 891 our_int64_array[3] != -0x45678123) 892 _dbus_assert_not_reached ("int64 array differs"); 893 #endif /* DBUS_HAVE_INT64 */ 894 895 if (our_double_array_len != 3) 896 _dbus_assert_not_reached ("double array had wrong length"); 897 898 /* On all IEEE machines (i.e. everything sane) exact equality 899 * should be preserved over the wire 900 */ 901 v_DOUBLE = 0.1234; 902 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[0], v_DOUBLE)) 903 _dbus_assert_not_reached ("double array had wrong values"); 904 v_DOUBLE = 9876.54321; 905 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[1], v_DOUBLE)) 906 _dbus_assert_not_reached ("double array had wrong values"); 907 v_DOUBLE = -300.0; 908 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[2], v_DOUBLE)) 909 _dbus_assert_not_reached ("double array had wrong values"); 910 911 if (our_byte_array_len != 4) 912 _dbus_assert_not_reached ("byte array had wrong length"); 913 914 if (our_byte_array[0] != 'a' || 915 our_byte_array[1] != 'b' || 916 our_byte_array[2] != 'c' || 917 our_byte_array[3] != 234) 918 _dbus_assert_not_reached ("byte array had wrong values"); 919 920 if (our_boolean_array_len != 5) 921 _dbus_assert_not_reached ("bool array had wrong length"); 922 923 if (our_boolean_array[0] != TRUE || 924 our_boolean_array[1] != FALSE || 925 our_boolean_array[2] != TRUE || 926 our_boolean_array[3] != TRUE || 927 our_boolean_array[4] != FALSE) 928 _dbus_assert_not_reached ("bool array had wrong values"); 929 930 if (our_string_array_len != 4) 931 _dbus_assert_not_reached ("string array was wrong length"); 932 933 if (strcmp (our_string_array[0], "Foo") != 0 || 934 strcmp (our_string_array[1], "bar") != 0 || 935 strcmp (our_string_array[2], "") != 0 || 936 strcmp (our_string_array[3], "woo woo woo woo") != 0) 937 _dbus_assert_not_reached ("string array had wrong values"); 938 939 dbus_free_string_array (our_string_array); 940 941 if (dbus_message_iter_next (&iter)) 942 _dbus_assert_not_reached ("Didn't reach end of arguments"); 943 } 944 945 /** 946 * @ingroup DBusMessageInternals 947 * Unit test for DBusMessage. 948 * 949 * @returns #TRUE on success. 950 */ 951 dbus_bool_t 952 _dbus_message_test (const char *test_data_dir) 953 { 954 DBusMessage *message, *message_without_unix_fds; 955 DBusMessageLoader *loader; 956 int i; 957 const char *data; 958 DBusMessage *copy; 959 const char *name1; 960 const char *name2; 961 const dbus_uint32_t our_uint32_array[] = 962 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; 963 const dbus_int32_t our_int32_array[] = 964 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; 965 const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array; 966 const dbus_int32_t *v_ARRAY_INT32 = our_int32_array; 967 #ifdef DBUS_HAVE_INT64 968 const dbus_uint64_t our_uint64_array[] = 969 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; 970 const dbus_int64_t our_int64_array[] = 971 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; 972 const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array; 973 const dbus_int64_t *v_ARRAY_INT64 = our_int64_array; 974 #endif 975 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" }; 976 const char **v_ARRAY_STRING = our_string_array; 977 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 }; 978 const double *v_ARRAY_DOUBLE = our_double_array; 979 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 }; 980 const unsigned char *v_ARRAY_BYTE = our_byte_array; 981 const dbus_bool_t our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE }; 982 const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array; 983 char sig[64]; 984 const char *s; 985 const char *v_STRING; 986 double v_DOUBLE; 987 dbus_int16_t v_INT16; 988 dbus_uint16_t v_UINT16; 989 dbus_int32_t v_INT32; 990 dbus_uint32_t v_UINT32; 991 #ifdef DBUS_HAVE_INT64 992 dbus_int64_t v_INT64; 993 dbus_uint64_t v_UINT64; 994 #endif 995 unsigned char v_BYTE; 996 unsigned char v2_BYTE; 997 dbus_bool_t v_BOOLEAN; 998 DBusMessageIter iter, array_iter, struct_iter; 999 #ifdef HAVE_UNIX_FD_PASSING 1000 int v_UNIX_FD; 1001 #endif 1002 char **decomposed; 1003 1004 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 1005 "/org/freedesktop/TestPath", 1006 "Foo.TestInterface", 1007 "TestMethod"); 1008 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); 1009 _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface", 1010 "TestMethod")); 1011 _dbus_assert (strcmp (dbus_message_get_path (message), 1012 "/org/freedesktop/TestPath") == 0); 1013 dbus_message_set_serial (message, 1234); 1014 1015 /* string length including nul byte not a multiple of 4 */ 1016 if (!dbus_message_set_sender (message, "org.foo.bar1")) 1017 _dbus_assert_not_reached ("out of memory"); 1018 1019 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1")); 1020 dbus_message_set_reply_serial (message, 5678); 1021 1022 _dbus_verbose_bytes_of_string (&message->header.data, 0, 1023 _dbus_string_get_length (&message->header.data)); 1024 _dbus_verbose_bytes_of_string (&message->body, 0, 1025 _dbus_string_get_length (&message->body)); 1026 1027 if (!dbus_message_set_sender (message, NULL)) 1028 _dbus_assert_not_reached ("out of memory"); 1029 1030 1031 _dbus_verbose_bytes_of_string (&message->header.data, 0, 1032 _dbus_string_get_length (&message->header.data)); 1033 _dbus_verbose_bytes_of_string (&message->body, 0, 1034 _dbus_string_get_length (&message->body)); 1035 1036 1037 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1")); 1038 _dbus_assert (dbus_message_get_serial (message) == 1234); 1039 _dbus_assert (dbus_message_get_reply_serial (message) == 5678); 1040 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); 1041 1042 _dbus_assert (dbus_message_get_no_reply (message) == FALSE); 1043 dbus_message_set_no_reply (message, TRUE); 1044 _dbus_assert (dbus_message_get_no_reply (message) == TRUE); 1045 dbus_message_set_no_reply (message, FALSE); 1046 _dbus_assert (dbus_message_get_no_reply (message) == FALSE); 1047 1048 /* Set/get some header fields */ 1049 1050 if (!dbus_message_set_path (message, "/foo")) 1051 _dbus_assert_not_reached ("out of memory"); 1052 _dbus_assert (strcmp (dbus_message_get_path (message), 1053 "/foo") == 0); 1054 1055 if (!dbus_message_set_interface (message, "org.Foo")) 1056 _dbus_assert_not_reached ("out of memory"); 1057 _dbus_assert (strcmp (dbus_message_get_interface (message), 1058 "org.Foo") == 0); 1059 1060 if (!dbus_message_set_member (message, "Bar")) 1061 _dbus_assert_not_reached ("out of memory"); 1062 _dbus_assert (strcmp (dbus_message_get_member (message), 1063 "Bar") == 0); 1064 1065 /* Set/get them with longer values */ 1066 if (!dbus_message_set_path (message, "/foo/bar")) 1067 _dbus_assert_not_reached ("out of memory"); 1068 _dbus_assert (strcmp (dbus_message_get_path (message), 1069 "/foo/bar") == 0); 1070 1071 if (!dbus_message_set_interface (message, "org.Foo.Bar")) 1072 _dbus_assert_not_reached ("out of memory"); 1073 _dbus_assert (strcmp (dbus_message_get_interface (message), 1074 "org.Foo.Bar") == 0); 1075 1076 if (!dbus_message_set_member (message, "BarFoo")) 1077 _dbus_assert_not_reached ("out of memory"); 1078 _dbus_assert (strcmp (dbus_message_get_member (message), 1079 "BarFoo") == 0); 1080 1081 /* Realloc shorter again */ 1082 1083 if (!dbus_message_set_path (message, "/foo")) 1084 _dbus_assert_not_reached ("out of memory"); 1085 _dbus_assert (strcmp (dbus_message_get_path (message), 1086 "/foo") == 0); 1087 1088 if (!dbus_message_set_interface (message, "org.Foo")) 1089 _dbus_assert_not_reached ("out of memory"); 1090 _dbus_assert (strcmp (dbus_message_get_interface (message), 1091 "org.Foo") == 0); 1092 1093 if (!dbus_message_set_member (message, "Bar")) 1094 _dbus_assert_not_reached ("out of memory"); 1095 _dbus_assert (strcmp (dbus_message_get_member (message), 1096 "Bar") == 0); 1097 1098 /* Path decomposing */ 1099 dbus_message_set_path (message, NULL); 1100 dbus_message_get_path_decomposed (message, &decomposed); 1101 _dbus_assert (decomposed == NULL); 1102 dbus_free_string_array (decomposed); 1103 1104 dbus_message_set_path (message, "/"); 1105 dbus_message_get_path_decomposed (message, &decomposed); 1106 _dbus_assert (decomposed != NULL); 1107 _dbus_assert (decomposed[0] == NULL); 1108 dbus_free_string_array (decomposed); 1109 1110 dbus_message_set_path (message, "/a/b"); 1111 dbus_message_get_path_decomposed (message, &decomposed); 1112 _dbus_assert (decomposed != NULL); 1113 _dbus_assert (strcmp (decomposed[0], "a") == 0); 1114 _dbus_assert (strcmp (decomposed[1], "b") == 0); 1115 _dbus_assert (decomposed[2] == NULL); 1116 dbus_free_string_array (decomposed); 1117 1118 dbus_message_set_path (message, "/spam/eggs"); 1119 dbus_message_get_path_decomposed (message, &decomposed); 1120 _dbus_assert (decomposed != NULL); 1121 _dbus_assert (strcmp (decomposed[0], "spam") == 0); 1122 _dbus_assert (strcmp (decomposed[1], "eggs") == 0); 1123 _dbus_assert (decomposed[2] == NULL); 1124 dbus_free_string_array (decomposed); 1125 1126 dbus_message_unref (message); 1127 1128 /* Test the vararg functions */ 1129 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 1130 "/org/freedesktop/TestPath", 1131 "Foo.TestInterface", 1132 "TestMethod"); 1133 dbus_message_set_serial (message, 1); 1134 dbus_message_set_reply_serial (message, 5678); 1135 1136 v_INT16 = -0x123; 1137 v_UINT16 = 0x123; 1138 v_INT32 = -0x12345678; 1139 v_UINT32 = 0x12300042; 1140 #ifdef DBUS_HAVE_INT64 1141 v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd); 1142 v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd); 1143 #endif 1144 v_STRING = "Test string"; 1145 v_DOUBLE = 3.14159; 1146 v_BOOLEAN = TRUE; 1147 v_BYTE = 42; 1148 v2_BYTE = 24; 1149 #ifdef HAVE_UNIX_FD_PASSING 1150 v_UNIX_FD = 1; 1151 #endif 1152 1153 dbus_message_append_args (message, 1154 DBUS_TYPE_INT16, &v_INT16, 1155 DBUS_TYPE_UINT16, &v_UINT16, 1156 DBUS_TYPE_INT32, &v_INT32, 1157 DBUS_TYPE_UINT32, &v_UINT32, 1158 #ifdef DBUS_HAVE_INT64 1159 DBUS_TYPE_INT64, &v_INT64, 1160 DBUS_TYPE_UINT64, &v_UINT64, 1161 #endif 1162 DBUS_TYPE_STRING, &v_STRING, 1163 DBUS_TYPE_DOUBLE, &v_DOUBLE, 1164 DBUS_TYPE_BOOLEAN, &v_BOOLEAN, 1165 DBUS_TYPE_BYTE, &v_BYTE, 1166 DBUS_TYPE_BYTE, &v2_BYTE, 1167 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32, 1168 _DBUS_N_ELEMENTS (our_uint32_array), 1169 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32, 1170 _DBUS_N_ELEMENTS (our_int32_array), 1171 #ifdef DBUS_HAVE_INT64 1172 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64, 1173 _DBUS_N_ELEMENTS (our_uint64_array), 1174 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64, 1175 _DBUS_N_ELEMENTS (our_int64_array), 1176 #endif 1177 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE, 1178 _DBUS_N_ELEMENTS (our_double_array), 1179 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE, 1180 _DBUS_N_ELEMENTS (our_byte_array), 1181 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN, 1182 _DBUS_N_ELEMENTS (our_boolean_array), 1183 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, 1184 _DBUS_N_ELEMENTS (our_string_array), 1185 1186 DBUS_TYPE_INVALID); 1187 1188 i = 0; 1189 sig[i++] = DBUS_TYPE_INT16; 1190 sig[i++] = DBUS_TYPE_UINT16; 1191 sig[i++] = DBUS_TYPE_INT32; 1192 sig[i++] = DBUS_TYPE_UINT32; 1193 #ifdef DBUS_HAVE_INT64 1194 sig[i++] = DBUS_TYPE_INT64; 1195 sig[i++] = DBUS_TYPE_UINT64; 1196 #endif 1197 sig[i++] = DBUS_TYPE_STRING; 1198 sig[i++] = DBUS_TYPE_DOUBLE; 1199 sig[i++] = DBUS_TYPE_BOOLEAN; 1200 sig[i++] = DBUS_TYPE_BYTE; 1201 sig[i++] = DBUS_TYPE_BYTE; 1202 sig[i++] = DBUS_TYPE_ARRAY; 1203 sig[i++] = DBUS_TYPE_UINT32; 1204 sig[i++] = DBUS_TYPE_ARRAY; 1205 sig[i++] = DBUS_TYPE_INT32; 1206 #ifdef DBUS_HAVE_INT64 1207 sig[i++] = DBUS_TYPE_ARRAY; 1208 sig[i++] = DBUS_TYPE_UINT64; 1209 sig[i++] = DBUS_TYPE_ARRAY; 1210 sig[i++] = DBUS_TYPE_INT64; 1211 #endif 1212 sig[i++] = DBUS_TYPE_ARRAY; 1213 sig[i++] = DBUS_TYPE_DOUBLE; 1214 sig[i++] = DBUS_TYPE_ARRAY; 1215 sig[i++] = DBUS_TYPE_BYTE; 1216 sig[i++] = DBUS_TYPE_ARRAY; 1217 sig[i++] = DBUS_TYPE_BOOLEAN; 1218 sig[i++] = DBUS_TYPE_ARRAY; 1219 sig[i++] = DBUS_TYPE_STRING; 1220 1221 message_without_unix_fds = dbus_message_copy(message); 1222 _dbus_assert(message_without_unix_fds); 1223 #ifdef HAVE_UNIX_FD_PASSING 1224 dbus_message_append_args (message, 1225 DBUS_TYPE_UNIX_FD, &v_UNIX_FD, 1226 DBUS_TYPE_INVALID); 1227 sig[i++] = DBUS_TYPE_UNIX_FD; 1228 #endif 1229 sig[i++] = DBUS_TYPE_INVALID; 1230 1231 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); 1232 1233 _dbus_verbose ("HEADER\n"); 1234 _dbus_verbose_bytes_of_string (&message->header.data, 0, 1235 _dbus_string_get_length (&message->header.data)); 1236 _dbus_verbose ("BODY\n"); 1237 _dbus_verbose_bytes_of_string (&message->body, 0, 1238 _dbus_string_get_length (&message->body)); 1239 1240 _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n", 1241 sig, dbus_message_get_signature (message)); 1242 1243 s = dbus_message_get_signature (message); 1244 1245 _dbus_assert (dbus_message_has_signature (message, sig)); 1246 _dbus_assert (strcmp (s, sig) == 0); 1247 1248 verify_test_message (message); 1249 1250 copy = dbus_message_copy (message); 1251 1252 _dbus_assert (dbus_message_get_reply_serial (message) == 1253 dbus_message_get_reply_serial (copy)); 1254 _dbus_assert (message->header.padding == copy->header.padding); 1255 1256 _dbus_assert (_dbus_string_get_length (&message->header.data) == 1257 _dbus_string_get_length (©->header.data)); 1258 1259 _dbus_assert (_dbus_string_get_length (&message->body) == 1260 _dbus_string_get_length (©->body)); 1261 1262 verify_test_message (copy); 1263 1264 name1 = dbus_message_get_interface (message); 1265 name2 = dbus_message_get_interface (copy); 1266 1267 _dbus_assert (strcmp (name1, name2) == 0); 1268 1269 name1 = dbus_message_get_member (message); 1270 name2 = dbus_message_get_member (copy); 1271 1272 _dbus_assert (strcmp (name1, name2) == 0); 1273 1274 dbus_message_unref (copy); 1275 1276 /* Message loader test */ 1277 dbus_message_lock (message); 1278 loader = _dbus_message_loader_new (); 1279 1280 /* check ref/unref */ 1281 _dbus_message_loader_ref (loader); 1282 _dbus_message_loader_unref (loader); 1283 1284 /* Write the header data one byte at a time */ 1285 data = _dbus_string_get_const_data (&message->header.data); 1286 for (i = 0; i < _dbus_string_get_length (&message->header.data); i++) 1287 { 1288 DBusString *buffer; 1289 1290 _dbus_message_loader_get_buffer (loader, &buffer); 1291 _dbus_string_append_byte (buffer, data[i]); 1292 _dbus_message_loader_return_buffer (loader, buffer, 1); 1293 } 1294 1295 /* Write the body data one byte at a time */ 1296 data = _dbus_string_get_const_data (&message->body); 1297 for (i = 0; i < _dbus_string_get_length (&message->body); i++) 1298 { 1299 DBusString *buffer; 1300 1301 _dbus_message_loader_get_buffer (loader, &buffer); 1302 _dbus_string_append_byte (buffer, data[i]); 1303 _dbus_message_loader_return_buffer (loader, buffer, 1); 1304 } 1305 1306 #ifdef HAVE_UNIX_FD_PASSING 1307 { 1308 int *unix_fds; 1309 unsigned n_unix_fds; 1310 /* Write unix fd */ 1311 _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds); 1312 _dbus_assert(n_unix_fds > 0); 1313 _dbus_assert(message->n_unix_fds == 1); 1314 unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL); 1315 _dbus_assert(unix_fds[0] >= 0); 1316 _dbus_message_loader_return_unix_fds(loader, unix_fds, 1); 1317 } 1318 #endif 1319 1320 dbus_message_unref (message); 1321 1322 /* Now pop back the message */ 1323 if (!_dbus_message_loader_queue_messages (loader)) 1324 _dbus_assert_not_reached ("no memory to queue messages"); 1325 1326 if (_dbus_message_loader_get_is_corrupted (loader)) 1327 _dbus_assert_not_reached ("message loader corrupted"); 1328 1329 message = _dbus_message_loader_pop_message (loader); 1330 if (!message) 1331 _dbus_assert_not_reached ("received a NULL message"); 1332 1333 if (dbus_message_get_reply_serial (message) != 5678) 1334 _dbus_assert_not_reached ("reply serial fields differ"); 1335 1336 dbus_message_unref (message); 1337 1338 /* ovveride the serial, since it was reset by dbus_message_copy() */ 1339 dbus_message_set_serial(message_without_unix_fds, 8901); 1340 1341 dbus_message_lock (message_without_unix_fds); 1342 1343 verify_test_message (message_without_unix_fds); 1344 1345 { 1346 /* Marshal and demarshal the message. */ 1347 1348 DBusMessage *message2; 1349 DBusError error = DBUS_ERROR_INIT; 1350 char *marshalled = NULL; 1351 int len = 0; 1352 char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx"; 1353 1354 if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len)) 1355 _dbus_assert_not_reached ("failed to marshal message"); 1356 1357 _dbus_assert (len != 0); 1358 _dbus_assert (marshalled != NULL); 1359 1360 _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len); 1361 message2 = dbus_message_demarshal (marshalled, len, &error); 1362 1363 _dbus_assert (message2 != NULL); 1364 _dbus_assert (!dbus_error_is_set (&error)); 1365 verify_test_message (message2); 1366 1367 dbus_message_unref (message2); 1368 dbus_free (marshalled); 1369 1370 /* Demarshal invalid message. */ 1371 1372 message2 = dbus_message_demarshal ("invalid", 7, &error); 1373 _dbus_assert (message2 == NULL); 1374 _dbus_assert (dbus_error_is_set (&error)); 1375 dbus_error_free (&error); 1376 1377 /* Demarshal invalid (empty) message. */ 1378 1379 message2 = dbus_message_demarshal ("", 0, &error); 1380 _dbus_assert (message2 == NULL); 1381 _dbus_assert (dbus_error_is_set (&error)); 1382 dbus_error_free (&error); 1383 1384 /* Bytes needed to demarshal empty message: 0 (more) */ 1385 1386 _dbus_assert (dbus_message_demarshal_bytes_needed ("", 0) == 0); 1387 1388 /* Bytes needed to demarshal invalid message: -1 (error). */ 1389 1390 _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1); 1391 } 1392 1393 dbus_message_unref (message_without_unix_fds); 1394 _dbus_message_loader_unref (loader); 1395 1396 check_memleaks (); 1397 _dbus_check_fdleaks(); 1398 1399 /* Check that we can abandon a container */ 1400 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 1401 "/org/freedesktop/TestPath", 1402 "Foo.TestInterface", 1403 "Method"); 1404 1405 dbus_message_iter_init_append (message, &iter); 1406 1407 _dbus_assert (dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 1408 (DBUS_STRUCT_BEGIN_CHAR_AS_STRING 1409 DBUS_TYPE_STRING_AS_STRING 1410 DBUS_TYPE_STRING_AS_STRING 1411 DBUS_STRUCT_END_CHAR_AS_STRING), 1412 &array_iter)); 1413 _dbus_assert (dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, 1414 NULL, &struct_iter)); 1415 1416 s = "peaches"; 1417 _dbus_assert (dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, 1418 &s)); 1419 1420 /* uh-oh, error, try and unwind */ 1421 1422 dbus_message_iter_abandon_container (&array_iter, &struct_iter); 1423 dbus_message_iter_abandon_container (&array_iter, &iter); 1424 1425 dbus_message_unref (message); 1426 1427 /* Load all the sample messages from the message factory */ 1428 { 1429 DBusMessageDataIter diter; 1430 DBusMessageData mdata; 1431 int count; 1432 1433 reset_validities_seen (); 1434 1435 count = 0; 1436 _dbus_message_data_iter_init (&diter); 1437 1438 while (_dbus_message_data_iter_get_and_next (&diter, 1439 &mdata)) 1440 { 1441 if (!dbus_internal_do_not_use_try_message_data (&mdata.data, 1442 mdata.expected_validity)) 1443 { 1444 _dbus_warn ("expected validity %d and did not get it\n", 1445 mdata.expected_validity); 1446 _dbus_assert_not_reached ("message data failed"); 1447 } 1448 1449 _dbus_message_data_free (&mdata); 1450 1451 count += 1; 1452 } 1453 1454 printf ("%d sample messages tested\n", count); 1455 1456 print_validities_seen (FALSE); 1457 print_validities_seen (TRUE); 1458 } 1459 1460 check_memleaks (); 1461 _dbus_check_fdleaks(); 1462 1463 /* Now load every message in test_data_dir if we have one */ 1464 if (test_data_dir == NULL) 1465 return TRUE; 1466 1467 return dbus_internal_do_not_use_foreach_message_file (test_data_dir, 1468 (DBusForeachMessageFileFunc) 1469 dbus_internal_do_not_use_try_message_file, 1470 NULL); 1471 } 1472 1473 #endif /* DBUS_BUILD_TESTS */ 1474