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