D-Bus
1.6.8
|
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 00002 /* dbus-message-util.c Would be in dbus-message.c, but only used by bus/tests 00003 * 00004 * Copyright (C) 2002, 2003, 2004, 2005 Red Hat Inc. 00005 * Copyright (C) 2002, 2003 CodeFactory AB 00006 * 00007 * Licensed under the Academic Free License version 2.1 00008 * 00009 * This program is free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00022 * 00023 */ 00024 00025 #include <config.h> 00026 #include "dbus-internals.h" 00027 #include "dbus-test.h" 00028 #include "dbus-message-private.h" 00029 #include "dbus-marshal-recursive.h" 00030 #include "dbus-string.h" 00031 #ifdef HAVE_UNIX_FD_PASSING 00032 #include "dbus-sysdeps-unix.h" 00033 #endif 00034 00035 #ifdef __linux__ 00036 /* Necessary for the Linux-specific fd leak checking code only */ 00037 #include <sys/types.h> 00038 #include <dirent.h> 00039 #include <stdlib.h> 00040 #include <errno.h> 00041 #endif 00042 00048 #ifdef DBUS_BUILD_TESTS 00049 00061 static dbus_bool_t 00062 dbus_message_iter_get_args (DBusMessageIter *iter, 00063 DBusError *error, 00064 int first_arg_type, 00065 ...) 00066 { 00067 dbus_bool_t retval; 00068 va_list var_args; 00069 00070 _dbus_return_val_if_fail (iter != NULL, FALSE); 00071 _dbus_return_val_if_error_is_set (error, FALSE); 00072 00073 va_start (var_args, first_arg_type); 00074 retval = _dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args); 00075 va_end (var_args); 00076 00077 return retval; 00078 } 00079 #endif /* DBUS_BUILD_TESTS */ 00080 00083 #ifdef DBUS_BUILD_TESTS 00084 #include "dbus-test.h" 00085 #include "dbus-message-factory.h" 00086 #include <stdio.h> 00087 #include <stdlib.h> 00088 00089 static int validities_seen[DBUS_VALIDITY_LAST + _DBUS_NEGATIVE_VALIDITY_COUNT]; 00090 00091 static void 00092 reset_validities_seen (void) 00093 { 00094 int i; 00095 i = 0; 00096 while (i < _DBUS_N_ELEMENTS (validities_seen)) 00097 { 00098 validities_seen[i] = 0; 00099 ++i; 00100 } 00101 } 00102 00103 static void 00104 record_validity_seen (DBusValidity validity) 00105 { 00106 validities_seen[validity + _DBUS_NEGATIVE_VALIDITY_COUNT] += 1; 00107 } 00108 00109 static void 00110 print_validities_seen (dbus_bool_t not_seen) 00111 { 00112 int i; 00113 i = 0; 00114 while (i < _DBUS_N_ELEMENTS (validities_seen)) 00115 { 00116 if ((i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_VALIDITY_UNKNOWN || 00117 (i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_INVALID_FOR_UNKNOWN_REASON) 00118 ; 00119 else if ((not_seen && validities_seen[i] == 0) || 00120 (!not_seen && validities_seen[i] > 0)) 00121 printf ("validity %3d seen %d times\n", 00122 i - _DBUS_NEGATIVE_VALIDITY_COUNT, 00123 validities_seen[i]); 00124 ++i; 00125 } 00126 } 00127 00128 static void 00129 check_memleaks (void) 00130 { 00131 dbus_shutdown (); 00132 00133 if (_dbus_get_malloc_blocks_outstanding () != 0) 00134 { 00135 _dbus_warn ("%d dbus_malloc blocks were not freed in %s\n", 00136 _dbus_get_malloc_blocks_outstanding (), __FILE__); 00137 _dbus_assert_not_reached ("memleaks"); 00138 } 00139 } 00140 00141 #ifdef __linux__ 00142 struct DBusInitialFDs { 00143 fd_set set; 00144 }; 00145 #endif 00146 00147 DBusInitialFDs * 00148 _dbus_check_fdleaks_enter (void) 00149 { 00150 #ifdef __linux__ 00151 DIR *d; 00152 DBusInitialFDs *fds; 00153 00154 /* this is plain malloc so it won't interfere with leak checking */ 00155 fds = malloc (sizeof (DBusInitialFDs)); 00156 _dbus_assert (fds != NULL); 00157 00158 /* This works on Linux only */ 00159 00160 if ((d = opendir ("/proc/self/fd"))) 00161 { 00162 struct dirent *de; 00163 00164 while ((de = readdir(d))) 00165 { 00166 long l; 00167 char *e = NULL; 00168 int fd; 00169 00170 if (de->d_name[0] == '.') 00171 continue; 00172 00173 errno = 0; 00174 l = strtol (de->d_name, &e, 10); 00175 _dbus_assert (errno == 0 && e && !*e); 00176 00177 fd = (int) l; 00178 00179 if (fd < 3) 00180 continue; 00181 00182 if (fd == dirfd (d)) 00183 continue; 00184 00185 FD_SET (fd, &fds->set); 00186 } 00187 00188 closedir (d); 00189 } 00190 00191 return fds; 00192 #else 00193 return NULL; 00194 #endif 00195 } 00196 00197 void 00198 _dbus_check_fdleaks_leave (DBusInitialFDs *fds) 00199 { 00200 #ifdef __linux__ 00201 DIR *d; 00202 00203 /* This works on Linux only */ 00204 00205 if ((d = opendir ("/proc/self/fd"))) 00206 { 00207 struct dirent *de; 00208 00209 while ((de = readdir(d))) 00210 { 00211 long l; 00212 char *e = NULL; 00213 int fd; 00214 00215 if (de->d_name[0] == '.') 00216 continue; 00217 00218 errno = 0; 00219 l = strtol (de->d_name, &e, 10); 00220 _dbus_assert (errno == 0 && e && !*e); 00221 00222 fd = (int) l; 00223 00224 if (fd < 3) 00225 continue; 00226 00227 if (fd == dirfd (d)) 00228 continue; 00229 00230 if (FD_ISSET (fd, &fds->set)) 00231 continue; 00232 00233 _dbus_warn ("file descriptor %i leaked in %s.\n", fd, __FILE__); 00234 _dbus_assert_not_reached ("fdleaks"); 00235 } 00236 00237 closedir (d); 00238 } 00239 00240 free (fds); 00241 #else 00242 _dbus_assert (fds == NULL); 00243 #endif 00244 } 00245 00246 static dbus_bool_t 00247 check_have_valid_message (DBusMessageLoader *loader) 00248 { 00249 DBusMessage *message; 00250 dbus_bool_t retval; 00251 00252 message = NULL; 00253 retval = FALSE; 00254 00255 if (_dbus_message_loader_get_is_corrupted (loader)) 00256 { 00257 _dbus_warn ("loader corrupted on message that was expected to be valid; invalid reason %d\n", 00258 loader->corruption_reason); 00259 goto failed; 00260 } 00261 00262 message = _dbus_message_loader_pop_message (loader); 00263 if (message == NULL) 00264 { 00265 _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n"); 00266 goto failed; 00267 } 00268 00269 if (_dbus_string_get_length (&loader->data) > 0) 00270 { 00271 _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n"); 00272 goto failed; 00273 } 00274 00275 #if 0 00276 /* FIXME */ 00277 /* Verify that we're able to properly deal with the message. 00278 * For example, this would detect improper handling of messages 00279 * in nonstandard byte order. 00280 */ 00281 if (!check_message_handling (message)) 00282 goto failed; 00283 #endif 00284 00285 record_validity_seen (DBUS_VALID); 00286 00287 retval = TRUE; 00288 00289 failed: 00290 if (message) 00291 dbus_message_unref (message); 00292 00293 return retval; 00294 } 00295 00296 static dbus_bool_t 00297 check_invalid_message (DBusMessageLoader *loader, 00298 DBusValidity expected_validity) 00299 { 00300 dbus_bool_t retval; 00301 00302 retval = FALSE; 00303 00304 if (!_dbus_message_loader_get_is_corrupted (loader)) 00305 { 00306 _dbus_warn ("loader not corrupted on message that was expected to be invalid\n"); 00307 goto failed; 00308 } 00309 00310 record_validity_seen (loader->corruption_reason); 00311 00312 if (expected_validity != DBUS_INVALID_FOR_UNKNOWN_REASON && 00313 loader->corruption_reason != expected_validity) 00314 { 00315 _dbus_warn ("expected message to be corrupted for reason %d and was corrupted for %d instead\n", 00316 expected_validity, loader->corruption_reason); 00317 goto failed; 00318 } 00319 00320 retval = TRUE; 00321 00322 failed: 00323 return retval; 00324 } 00325 00326 static dbus_bool_t 00327 check_incomplete_message (DBusMessageLoader *loader) 00328 { 00329 DBusMessage *message; 00330 dbus_bool_t retval; 00331 00332 message = NULL; 00333 retval = FALSE; 00334 00335 if (_dbus_message_loader_get_is_corrupted (loader)) 00336 { 00337 _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete), corruption reason %d\n", 00338 loader->corruption_reason); 00339 goto failed; 00340 } 00341 00342 message = _dbus_message_loader_pop_message (loader); 00343 if (message != NULL) 00344 { 00345 _dbus_warn ("loaded message that was expected to be incomplete\n"); 00346 goto failed; 00347 } 00348 00349 record_validity_seen (DBUS_VALID_BUT_INCOMPLETE); 00350 retval = TRUE; 00351 00352 failed: 00353 if (message) 00354 dbus_message_unref (message); 00355 return retval; 00356 } 00357 00358 static dbus_bool_t 00359 check_loader_results (DBusMessageLoader *loader, 00360 DBusValidity expected_validity) 00361 { 00362 if (!_dbus_message_loader_queue_messages (loader)) 00363 _dbus_assert_not_reached ("no memory to queue messages"); 00364 00365 if (expected_validity == DBUS_VALID) 00366 return check_have_valid_message (loader); 00367 else if (expected_validity == DBUS_VALID_BUT_INCOMPLETE) 00368 return check_incomplete_message (loader); 00369 else if (expected_validity == DBUS_VALIDITY_UNKNOWN) 00370 { 00371 /* here we just know we didn't segfault and that was the 00372 * only test. Also, we record that we got coverage 00373 * for the validity reason. 00374 */ 00375 if (_dbus_message_loader_get_is_corrupted (loader)) 00376 record_validity_seen (loader->corruption_reason); 00377 00378 return TRUE; 00379 } 00380 else 00381 return check_invalid_message (loader, expected_validity); 00382 } 00383 00391 dbus_bool_t 00392 dbus_internal_do_not_use_load_message_file (const DBusString *filename, 00393 DBusString *data) 00394 { 00395 dbus_bool_t retval; 00396 DBusError error = DBUS_ERROR_INIT; 00397 00398 retval = FALSE; 00399 00400 _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename)); 00401 if (!_dbus_file_get_contents (data, filename, &error)) 00402 { 00403 _dbus_warn ("Could not load message file %s: %s\n", 00404 _dbus_string_get_const_data (filename), 00405 error.message); 00406 dbus_error_free (&error); 00407 goto failed; 00408 } 00409 00410 retval = TRUE; 00411 00412 failed: 00413 00414 return retval; 00415 } 00416 00425 dbus_bool_t 00426 dbus_internal_do_not_use_try_message_file (const DBusString *filename, 00427 DBusValidity expected_validity) 00428 { 00429 DBusString data; 00430 dbus_bool_t retval; 00431 00432 retval = FALSE; 00433 00434 if (!_dbus_string_init (&data)) 00435 _dbus_assert_not_reached ("could not allocate string\n"); 00436 00437 if (!dbus_internal_do_not_use_load_message_file (filename, &data)) 00438 goto failed; 00439 00440 retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity); 00441 00442 failed: 00443 00444 if (!retval) 00445 { 00446 if (_dbus_string_get_length (&data) > 0) 00447 _dbus_verbose_bytes_of_string (&data, 0, 00448 _dbus_string_get_length (&data)); 00449 00450 _dbus_warn ("Failed message loader test on %s\n", 00451 _dbus_string_get_const_data (filename)); 00452 } 00453 00454 _dbus_string_free (&data); 00455 00456 return retval; 00457 } 00458 00467 dbus_bool_t 00468 dbus_internal_do_not_use_try_message_data (const DBusString *data, 00469 DBusValidity expected_validity) 00470 { 00471 DBusMessageLoader *loader; 00472 dbus_bool_t retval; 00473 int len; 00474 int i; 00475 00476 loader = NULL; 00477 retval = FALSE; 00478 00479 /* Write the data one byte at a time */ 00480 00481 loader = _dbus_message_loader_new (); 00482 00483 /* check some trivial loader functions */ 00484 _dbus_message_loader_ref (loader); 00485 _dbus_message_loader_unref (loader); 00486 _dbus_message_loader_get_max_message_size (loader); 00487 00488 len = _dbus_string_get_length (data); 00489 for (i = 0; i < len; i++) 00490 { 00491 DBusString *buffer; 00492 00493 _dbus_message_loader_get_buffer (loader, &buffer); 00494 _dbus_string_append_byte (buffer, 00495 _dbus_string_get_byte (data, i)); 00496 _dbus_message_loader_return_buffer (loader, buffer, 1); 00497 } 00498 00499 if (!check_loader_results (loader, expected_validity)) 00500 goto failed; 00501 00502 _dbus_message_loader_unref (loader); 00503 loader = NULL; 00504 00505 /* Write the data all at once */ 00506 00507 loader = _dbus_message_loader_new (); 00508 00509 { 00510 DBusString *buffer; 00511 00512 _dbus_message_loader_get_buffer (loader, &buffer); 00513 _dbus_string_copy (data, 0, buffer, 00514 _dbus_string_get_length (buffer)); 00515 _dbus_message_loader_return_buffer (loader, buffer, 1); 00516 } 00517 00518 if (!check_loader_results (loader, expected_validity)) 00519 goto failed; 00520 00521 _dbus_message_loader_unref (loader); 00522 loader = NULL; 00523 00524 /* Write the data 2 bytes at a time */ 00525 00526 loader = _dbus_message_loader_new (); 00527 00528 len = _dbus_string_get_length (data); 00529 for (i = 0; i < len; i += 2) 00530 { 00531 DBusString *buffer; 00532 00533 _dbus_message_loader_get_buffer (loader, &buffer); 00534 _dbus_string_append_byte (buffer, 00535 _dbus_string_get_byte (data, i)); 00536 if ((i+1) < len) 00537 _dbus_string_append_byte (buffer, 00538 _dbus_string_get_byte (data, i+1)); 00539 _dbus_message_loader_return_buffer (loader, buffer, 1); 00540 } 00541 00542 if (!check_loader_results (loader, expected_validity)) 00543 goto failed; 00544 00545 _dbus_message_loader_unref (loader); 00546 loader = NULL; 00547 00548 retval = TRUE; 00549 00550 failed: 00551 00552 if (loader) 00553 _dbus_message_loader_unref (loader); 00554 00555 return retval; 00556 } 00557 00558 static dbus_bool_t 00559 process_test_subdir (const DBusString *test_base_dir, 00560 const char *subdir, 00561 DBusValidity expected_validity, 00562 DBusForeachMessageFileFunc function, 00563 void *user_data) 00564 { 00565 DBusString test_directory; 00566 DBusString filename; 00567 DBusDirIter *dir; 00568 dbus_bool_t retval; 00569 DBusError error = DBUS_ERROR_INIT; 00570 00571 retval = FALSE; 00572 dir = NULL; 00573 00574 if (!_dbus_string_init (&test_directory)) 00575 _dbus_assert_not_reached ("didn't allocate test_directory\n"); 00576 00577 _dbus_string_init_const (&filename, subdir); 00578 00579 if (!_dbus_string_copy (test_base_dir, 0, 00580 &test_directory, 0)) 00581 _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory"); 00582 00583 if (!_dbus_concat_dir_and_file (&test_directory, &filename)) 00584 _dbus_assert_not_reached ("couldn't allocate full path"); 00585 00586 _dbus_string_free (&filename); 00587 if (!_dbus_string_init (&filename)) 00588 _dbus_assert_not_reached ("didn't allocate filename string\n"); 00589 00590 dir = _dbus_directory_open (&test_directory, &error); 00591 if (dir == NULL) 00592 { 00593 _dbus_warn ("Could not open %s: %s\n", 00594 _dbus_string_get_const_data (&test_directory), 00595 error.message); 00596 dbus_error_free (&error); 00597 goto failed; 00598 } 00599 00600 printf ("Testing %s:\n", subdir); 00601 00602 next: 00603 while (_dbus_directory_get_next_file (dir, &filename, &error)) 00604 { 00605 DBusString full_path; 00606 00607 if (!_dbus_string_init (&full_path)) 00608 _dbus_assert_not_reached ("couldn't init string"); 00609 00610 if (!_dbus_string_copy (&test_directory, 0, &full_path, 0)) 00611 _dbus_assert_not_reached ("couldn't copy dir to full_path"); 00612 00613 if (!_dbus_concat_dir_and_file (&full_path, &filename)) 00614 _dbus_assert_not_reached ("couldn't concat file to dir"); 00615 00616 if (_dbus_string_ends_with_c_str (&filename, ".message-raw")) 00617 ; 00618 else 00619 { 00620 if (_dbus_string_ends_with_c_str (&filename, ".message")) 00621 { 00622 printf ("SKIP: Could not load %s, message builder language no longer supported\n", 00623 _dbus_string_get_const_data (&filename)); 00624 } 00625 00626 _dbus_verbose ("Skipping non-.message file %s\n", 00627 _dbus_string_get_const_data (&filename)); 00628 _dbus_string_free (&full_path); 00629 goto next; 00630 } 00631 00632 printf (" %s\n", 00633 _dbus_string_get_const_data (&filename)); 00634 00635 if (! (*function) (&full_path, 00636 expected_validity, user_data)) 00637 { 00638 _dbus_string_free (&full_path); 00639 goto failed; 00640 } 00641 else 00642 _dbus_string_free (&full_path); 00643 } 00644 00645 if (dbus_error_is_set (&error)) 00646 { 00647 _dbus_warn ("Could not get next file in %s: %s\n", 00648 _dbus_string_get_const_data (&test_directory), 00649 error.message); 00650 dbus_error_free (&error); 00651 goto failed; 00652 } 00653 00654 retval = TRUE; 00655 00656 failed: 00657 00658 if (dir) 00659 _dbus_directory_close (dir); 00660 _dbus_string_free (&test_directory); 00661 _dbus_string_free (&filename); 00662 00663 return retval; 00664 } 00665 00675 dbus_bool_t 00676 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir, 00677 DBusForeachMessageFileFunc func, 00678 void *user_data) 00679 { 00680 DBusString test_directory; 00681 dbus_bool_t retval; 00682 00683 retval = FALSE; 00684 00685 _dbus_string_init_const (&test_directory, test_data_dir); 00686 00687 if (!process_test_subdir (&test_directory, "valid-messages", 00688 DBUS_VALID, func, user_data)) 00689 goto failed; 00690 00691 check_memleaks (); 00692 00693 if (!process_test_subdir (&test_directory, "invalid-messages", 00694 DBUS_INVALID_FOR_UNKNOWN_REASON, func, user_data)) 00695 goto failed; 00696 00697 check_memleaks (); 00698 00699 if (!process_test_subdir (&test_directory, "incomplete-messages", 00700 DBUS_VALID_BUT_INCOMPLETE, func, user_data)) 00701 goto failed; 00702 00703 check_memleaks (); 00704 00705 retval = TRUE; 00706 00707 failed: 00708 00709 _dbus_string_free (&test_directory); 00710 00711 return retval; 00712 } 00713 00714 #if 0 00715 #define GET_AND_CHECK(iter, typename, literal) \ 00716 do { \ 00717 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \ 00718 _dbus_assert_not_reached ("got wrong argument type from message iter"); \ 00719 dbus_message_iter_get_basic (&iter, &v_##typename); \ 00720 if (v_##typename != literal) \ 00721 _dbus_assert_not_reached ("got wrong value from message iter"); \ 00722 } while (0) 00723 00724 #define GET_AND_CHECK_STRCMP(iter, typename, literal) \ 00725 do { \ 00726 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \ 00727 _dbus_assert_not_reached ("got wrong argument type from message iter"); \ 00728 dbus_message_iter_get_basic (&iter, &v_##typename); \ 00729 if (strcmp (v_##typename, literal) != 0) \ 00730 _dbus_assert_not_reached ("got wrong value from message iter"); \ 00731 } while (0) 00732 00733 #define GET_AND_CHECK_AND_NEXT(iter, typename, literal) \ 00734 do { \ 00735 GET_AND_CHECK(iter, typename, literal); \ 00736 if (!dbus_message_iter_next (&iter)) \ 00737 _dbus_assert_not_reached ("failed to move iter to next"); \ 00738 } while (0) 00739 00740 #define GET_AND_CHECK_STRCMP_AND_NEXT(iter, typename, literal) \ 00741 do { \ 00742 GET_AND_CHECK_STRCMP(iter, typename, literal); \ 00743 if (!dbus_message_iter_next (&iter)) \ 00744 _dbus_assert_not_reached ("failed to move iter to next"); \ 00745 } while (0) 00746 00747 static void 00748 message_iter_test (DBusMessage *message) 00749 { 00750 DBusMessageIter iter, array, array2; 00751 const char *v_STRING; 00752 double v_DOUBLE; 00753 dbus_int16_t v_INT16; 00754 dbus_uint16_t v_UINT16; 00755 dbus_int32_t v_INT32; 00756 dbus_uint32_t v_UINT32; 00757 #ifdef DBUS_HAVE_INT64 00758 dbus_int64_t v_INT64; 00759 dbus_uint64_t v_UINT64; 00760 #endif 00761 unsigned char v_BYTE; 00762 dbus_bool_t v_BOOLEAN; 00763 00764 const dbus_int32_t *our_int_array; 00765 int len; 00766 00767 dbus_message_iter_init (message, &iter); 00768 00769 GET_AND_CHECK_STRCMP_AND_NEXT (iter, STRING, "Test string"); 00770 GET_AND_CHECK_AND_NEXT (iter, INT32, -0x12345678); 00771 GET_AND_CHECK_AND_NEXT (iter, UINT32, 0xedd1e); 00772 GET_AND_CHECK_AND_NEXT (iter, DOUBLE, 3.14159); 00773 00774 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) 00775 _dbus_assert_not_reached ("Argument type not an array"); 00776 00777 if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_DOUBLE) 00778 _dbus_assert_not_reached ("Array type not double"); 00779 00780 dbus_message_iter_recurse (&iter, &array); 00781 00782 GET_AND_CHECK_AND_NEXT (array, DOUBLE, 1.5); 00783 GET_AND_CHECK (array, DOUBLE, 2.5); 00784 00785 if (dbus_message_iter_next (&array)) 00786 _dbus_assert_not_reached ("Didn't reach end of array"); 00787 00788 if (!dbus_message_iter_next (&iter)) 00789 _dbus_assert_not_reached ("Reached end of arguments"); 00790 00791 GET_AND_CHECK_AND_NEXT (iter, BYTE, 0xF0); 00792 00793 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) 00794 _dbus_assert_not_reached ("no array"); 00795 00796 if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_INT32) 00797 _dbus_assert_not_reached ("Array type not int32"); 00798 00799 /* Empty array */ 00800 dbus_message_iter_recurse (&iter, &array); 00801 00802 if (dbus_message_iter_next (&array)) 00803 _dbus_assert_not_reached ("Didn't reach end of array"); 00804 00805 if (!dbus_message_iter_next (&iter)) 00806 _dbus_assert_not_reached ("Reached end of arguments"); 00807 00808 GET_AND_CHECK (iter, BYTE, 0xF0); 00809 00810 if (dbus_message_iter_next (&iter)) 00811 _dbus_assert_not_reached ("Didn't reach end of arguments"); 00812 } 00813 #endif 00814 00815 static void 00816 verify_test_message (DBusMessage *message) 00817 { 00818 DBusMessageIter iter; 00819 DBusError error = DBUS_ERROR_INIT; 00820 dbus_int16_t our_int16; 00821 dbus_uint16_t our_uint16; 00822 dbus_int32_t our_int; 00823 dbus_uint32_t our_uint; 00824 const char *our_str; 00825 double our_double; 00826 double v_DOUBLE; 00827 dbus_bool_t our_bool; 00828 unsigned char our_byte_1, our_byte_2; 00829 const dbus_uint32_t *our_uint32_array = (void*)0xdeadbeef; 00830 int our_uint32_array_len; 00831 dbus_int32_t *our_int32_array = (void*)0xdeadbeef; 00832 int our_int32_array_len; 00833 #ifdef DBUS_HAVE_INT64 00834 dbus_int64_t our_int64; 00835 dbus_uint64_t our_uint64; 00836 dbus_int64_t *our_uint64_array = (void*)0xdeadbeef; 00837 int our_uint64_array_len; 00838 const dbus_int64_t *our_int64_array = (void*)0xdeadbeef; 00839 int our_int64_array_len; 00840 #endif 00841 const double *our_double_array = (void*)0xdeadbeef; 00842 int our_double_array_len; 00843 const unsigned char *our_byte_array = (void*)0xdeadbeef; 00844 int our_byte_array_len; 00845 const dbus_bool_t *our_boolean_array = (void*)0xdeadbeef; 00846 int our_boolean_array_len; 00847 char **our_string_array; 00848 int our_string_array_len; 00849 00850 dbus_message_iter_init (message, &iter); 00851 00852 if (!dbus_message_iter_get_args (&iter, &error, 00853 DBUS_TYPE_INT16, &our_int16, 00854 DBUS_TYPE_UINT16, &our_uint16, 00855 DBUS_TYPE_INT32, &our_int, 00856 DBUS_TYPE_UINT32, &our_uint, 00857 #ifdef DBUS_HAVE_INT64 00858 DBUS_TYPE_INT64, &our_int64, 00859 DBUS_TYPE_UINT64, &our_uint64, 00860 #endif 00861 DBUS_TYPE_STRING, &our_str, 00862 DBUS_TYPE_DOUBLE, &our_double, 00863 DBUS_TYPE_BOOLEAN, &our_bool, 00864 DBUS_TYPE_BYTE, &our_byte_1, 00865 DBUS_TYPE_BYTE, &our_byte_2, 00866 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 00867 &our_uint32_array, &our_uint32_array_len, 00868 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, 00869 &our_int32_array, &our_int32_array_len, 00870 #ifdef DBUS_HAVE_INT64 00871 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, 00872 &our_uint64_array, &our_uint64_array_len, 00873 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, 00874 &our_int64_array, &our_int64_array_len, 00875 #endif 00876 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, 00877 &our_double_array, &our_double_array_len, 00878 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, 00879 &our_byte_array, &our_byte_array_len, 00880 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, 00881 &our_boolean_array, &our_boolean_array_len, 00882 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 00883 &our_string_array, &our_string_array_len, 00884 0)) 00885 { 00886 _dbus_warn ("error: %s - %s\n", error.name, 00887 (error.message != NULL) ? error.message : "no message"); 00888 _dbus_assert_not_reached ("Could not get arguments"); 00889 } 00890 00891 if (our_int16 != -0x123) 00892 _dbus_assert_not_reached ("16-bit integers differ!"); 00893 00894 if (our_uint16 != 0x123) 00895 _dbus_assert_not_reached ("16-bit uints differ!"); 00896 00897 if (our_int != -0x12345678) 00898 _dbus_assert_not_reached ("integers differ!"); 00899 00900 if (our_uint != 0x12300042) 00901 _dbus_assert_not_reached ("uints differ!"); 00902 00903 #ifdef DBUS_HAVE_INT64 00904 if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd)) 00905 _dbus_assert_not_reached ("64-bit integers differ!"); 00906 if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd)) 00907 _dbus_assert_not_reached ("64-bit unsigned integers differ!"); 00908 #endif 00909 00910 v_DOUBLE = 3.14159; 00911 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double, v_DOUBLE)) 00912 _dbus_assert_not_reached ("doubles differ!"); 00913 00914 if (strcmp (our_str, "Test string") != 0) 00915 _dbus_assert_not_reached ("strings differ!"); 00916 00917 if (!our_bool) 00918 _dbus_assert_not_reached ("booleans differ"); 00919 00920 if (our_byte_1 != 42) 00921 _dbus_assert_not_reached ("bytes differ!"); 00922 00923 if (our_byte_2 != 24) 00924 _dbus_assert_not_reached ("bytes differ!"); 00925 00926 if (our_uint32_array_len != 4 || 00927 our_uint32_array[0] != 0x12345678 || 00928 our_uint32_array[1] != 0x23456781 || 00929 our_uint32_array[2] != 0x34567812 || 00930 our_uint32_array[3] != 0x45678123) 00931 _dbus_assert_not_reached ("uint array differs"); 00932 00933 if (our_int32_array_len != 4 || 00934 our_int32_array[0] != 0x12345678 || 00935 our_int32_array[1] != -0x23456781 || 00936 our_int32_array[2] != 0x34567812 || 00937 our_int32_array[3] != -0x45678123) 00938 _dbus_assert_not_reached ("int array differs"); 00939 00940 #ifdef DBUS_HAVE_INT64 00941 if (our_uint64_array_len != 4 || 00942 our_uint64_array[0] != 0x12345678 || 00943 our_uint64_array[1] != 0x23456781 || 00944 our_uint64_array[2] != 0x34567812 || 00945 our_uint64_array[3] != 0x45678123) 00946 _dbus_assert_not_reached ("uint64 array differs"); 00947 00948 if (our_int64_array_len != 4 || 00949 our_int64_array[0] != 0x12345678 || 00950 our_int64_array[1] != -0x23456781 || 00951 our_int64_array[2] != 0x34567812 || 00952 our_int64_array[3] != -0x45678123) 00953 _dbus_assert_not_reached ("int64 array differs"); 00954 #endif /* DBUS_HAVE_INT64 */ 00955 00956 if (our_double_array_len != 3) 00957 _dbus_assert_not_reached ("double array had wrong length"); 00958 00959 /* On all IEEE machines (i.e. everything sane) exact equality 00960 * should be preserved over the wire 00961 */ 00962 v_DOUBLE = 0.1234; 00963 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[0], v_DOUBLE)) 00964 _dbus_assert_not_reached ("double array had wrong values"); 00965 v_DOUBLE = 9876.54321; 00966 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[1], v_DOUBLE)) 00967 _dbus_assert_not_reached ("double array had wrong values"); 00968 v_DOUBLE = -300.0; 00969 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[2], v_DOUBLE)) 00970 _dbus_assert_not_reached ("double array had wrong values"); 00971 00972 if (our_byte_array_len != 4) 00973 _dbus_assert_not_reached ("byte array had wrong length"); 00974 00975 if (our_byte_array[0] != 'a' || 00976 our_byte_array[1] != 'b' || 00977 our_byte_array[2] != 'c' || 00978 our_byte_array[3] != 234) 00979 _dbus_assert_not_reached ("byte array had wrong values"); 00980 00981 if (our_boolean_array_len != 5) 00982 _dbus_assert_not_reached ("bool array had wrong length"); 00983 00984 if (our_boolean_array[0] != TRUE || 00985 our_boolean_array[1] != FALSE || 00986 our_boolean_array[2] != TRUE || 00987 our_boolean_array[3] != TRUE || 00988 our_boolean_array[4] != FALSE) 00989 _dbus_assert_not_reached ("bool array had wrong values"); 00990 00991 if (our_string_array_len != 4) 00992 _dbus_assert_not_reached ("string array was wrong length"); 00993 00994 if (strcmp (our_string_array[0], "Foo") != 0 || 00995 strcmp (our_string_array[1], "bar") != 0 || 00996 strcmp (our_string_array[2], "") != 0 || 00997 strcmp (our_string_array[3], "woo woo woo woo") != 0) 00998 _dbus_assert_not_reached ("string array had wrong values"); 00999 01000 dbus_free_string_array (our_string_array); 01001 01002 if (dbus_message_iter_next (&iter)) 01003 _dbus_assert_not_reached ("Didn't reach end of arguments"); 01004 } 01005 01012 dbus_bool_t 01013 _dbus_message_test (const char *test_data_dir) 01014 { 01015 DBusMessage *message, *message_without_unix_fds; 01016 DBusMessageLoader *loader; 01017 int i; 01018 const char *data; 01019 DBusMessage *copy; 01020 const char *name1; 01021 const char *name2; 01022 const dbus_uint32_t our_uint32_array[] = 01023 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; 01024 const dbus_int32_t our_int32_array[] = 01025 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; 01026 const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array; 01027 const dbus_int32_t *v_ARRAY_INT32 = our_int32_array; 01028 #ifdef DBUS_HAVE_INT64 01029 const dbus_uint64_t our_uint64_array[] = 01030 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; 01031 const dbus_int64_t our_int64_array[] = 01032 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; 01033 const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array; 01034 const dbus_int64_t *v_ARRAY_INT64 = our_int64_array; 01035 #endif 01036 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" }; 01037 const char **v_ARRAY_STRING = our_string_array; 01038 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 }; 01039 const double *v_ARRAY_DOUBLE = our_double_array; 01040 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 }; 01041 const unsigned char *v_ARRAY_BYTE = our_byte_array; 01042 const dbus_bool_t our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE }; 01043 const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array; 01044 char sig[64]; 01045 const char *s; 01046 const char *v_STRING; 01047 double v_DOUBLE; 01048 dbus_int16_t v_INT16; 01049 dbus_uint16_t v_UINT16; 01050 dbus_int32_t v_INT32; 01051 dbus_uint32_t v_UINT32; 01052 #ifdef DBUS_HAVE_INT64 01053 dbus_int64_t v_INT64; 01054 dbus_uint64_t v_UINT64; 01055 #endif 01056 unsigned char v_BYTE; 01057 unsigned char v2_BYTE; 01058 dbus_bool_t v_BOOLEAN; 01059 DBusMessageIter iter, array_iter, struct_iter; 01060 #ifdef HAVE_UNIX_FD_PASSING 01061 int v_UNIX_FD; 01062 #endif 01063 char **decomposed; 01064 DBusInitialFDs *initial_fds; 01065 01066 initial_fds = _dbus_check_fdleaks_enter (); 01067 01068 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01069 "/org/freedesktop/TestPath", 01070 "Foo.TestInterface", 01071 "TestMethod"); 01072 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); 01073 _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface", 01074 "TestMethod")); 01075 _dbus_assert (strcmp (dbus_message_get_path (message), 01076 "/org/freedesktop/TestPath") == 0); 01077 dbus_message_set_serial (message, 1234); 01078 01079 /* string length including nul byte not a multiple of 4 */ 01080 if (!dbus_message_set_sender (message, "org.foo.bar1")) 01081 _dbus_assert_not_reached ("out of memory"); 01082 01083 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1")); 01084 dbus_message_set_reply_serial (message, 5678); 01085 01086 _dbus_verbose_bytes_of_string (&message->header.data, 0, 01087 _dbus_string_get_length (&message->header.data)); 01088 _dbus_verbose_bytes_of_string (&message->body, 0, 01089 _dbus_string_get_length (&message->body)); 01090 01091 if (!dbus_message_set_sender (message, NULL)) 01092 _dbus_assert_not_reached ("out of memory"); 01093 01094 01095 _dbus_verbose_bytes_of_string (&message->header.data, 0, 01096 _dbus_string_get_length (&message->header.data)); 01097 _dbus_verbose_bytes_of_string (&message->body, 0, 01098 _dbus_string_get_length (&message->body)); 01099 01100 01101 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1")); 01102 _dbus_assert (dbus_message_get_serial (message) == 1234); 01103 _dbus_assert (dbus_message_get_reply_serial (message) == 5678); 01104 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); 01105 01106 _dbus_assert (dbus_message_get_no_reply (message) == FALSE); 01107 dbus_message_set_no_reply (message, TRUE); 01108 _dbus_assert (dbus_message_get_no_reply (message) == TRUE); 01109 dbus_message_set_no_reply (message, FALSE); 01110 _dbus_assert (dbus_message_get_no_reply (message) == FALSE); 01111 01112 /* Set/get some header fields */ 01113 01114 if (!dbus_message_set_path (message, "/foo")) 01115 _dbus_assert_not_reached ("out of memory"); 01116 _dbus_assert (strcmp (dbus_message_get_path (message), 01117 "/foo") == 0); 01118 01119 if (!dbus_message_set_interface (message, "org.Foo")) 01120 _dbus_assert_not_reached ("out of memory"); 01121 _dbus_assert (strcmp (dbus_message_get_interface (message), 01122 "org.Foo") == 0); 01123 01124 if (!dbus_message_set_member (message, "Bar")) 01125 _dbus_assert_not_reached ("out of memory"); 01126 _dbus_assert (strcmp (dbus_message_get_member (message), 01127 "Bar") == 0); 01128 01129 /* Set/get them with longer values */ 01130 if (!dbus_message_set_path (message, "/foo/bar")) 01131 _dbus_assert_not_reached ("out of memory"); 01132 _dbus_assert (strcmp (dbus_message_get_path (message), 01133 "/foo/bar") == 0); 01134 01135 if (!dbus_message_set_interface (message, "org.Foo.Bar")) 01136 _dbus_assert_not_reached ("out of memory"); 01137 _dbus_assert (strcmp (dbus_message_get_interface (message), 01138 "org.Foo.Bar") == 0); 01139 01140 if (!dbus_message_set_member (message, "BarFoo")) 01141 _dbus_assert_not_reached ("out of memory"); 01142 _dbus_assert (strcmp (dbus_message_get_member (message), 01143 "BarFoo") == 0); 01144 01145 /* Realloc shorter again */ 01146 01147 if (!dbus_message_set_path (message, "/foo")) 01148 _dbus_assert_not_reached ("out of memory"); 01149 _dbus_assert (strcmp (dbus_message_get_path (message), 01150 "/foo") == 0); 01151 01152 if (!dbus_message_set_interface (message, "org.Foo")) 01153 _dbus_assert_not_reached ("out of memory"); 01154 _dbus_assert (strcmp (dbus_message_get_interface (message), 01155 "org.Foo") == 0); 01156 01157 if (!dbus_message_set_member (message, "Bar")) 01158 _dbus_assert_not_reached ("out of memory"); 01159 _dbus_assert (strcmp (dbus_message_get_member (message), 01160 "Bar") == 0); 01161 01162 /* Path decomposing */ 01163 dbus_message_set_path (message, NULL); 01164 dbus_message_get_path_decomposed (message, &decomposed); 01165 _dbus_assert (decomposed == NULL); 01166 dbus_free_string_array (decomposed); 01167 01168 dbus_message_set_path (message, "/"); 01169 dbus_message_get_path_decomposed (message, &decomposed); 01170 _dbus_assert (decomposed != NULL); 01171 _dbus_assert (decomposed[0] == NULL); 01172 dbus_free_string_array (decomposed); 01173 01174 dbus_message_set_path (message, "/a/b"); 01175 dbus_message_get_path_decomposed (message, &decomposed); 01176 _dbus_assert (decomposed != NULL); 01177 _dbus_assert (strcmp (decomposed[0], "a") == 0); 01178 _dbus_assert (strcmp (decomposed[1], "b") == 0); 01179 _dbus_assert (decomposed[2] == NULL); 01180 dbus_free_string_array (decomposed); 01181 01182 dbus_message_set_path (message, "/spam/eggs"); 01183 dbus_message_get_path_decomposed (message, &decomposed); 01184 _dbus_assert (decomposed != NULL); 01185 _dbus_assert (strcmp (decomposed[0], "spam") == 0); 01186 _dbus_assert (strcmp (decomposed[1], "eggs") == 0); 01187 _dbus_assert (decomposed[2] == NULL); 01188 dbus_free_string_array (decomposed); 01189 01190 dbus_message_unref (message); 01191 01192 /* Test the vararg functions */ 01193 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01194 "/org/freedesktop/TestPath", 01195 "Foo.TestInterface", 01196 "TestMethod"); 01197 dbus_message_set_serial (message, 1); 01198 dbus_message_set_reply_serial (message, 5678); 01199 01200 v_INT16 = -0x123; 01201 v_UINT16 = 0x123; 01202 v_INT32 = -0x12345678; 01203 v_UINT32 = 0x12300042; 01204 #ifdef DBUS_HAVE_INT64 01205 v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd); 01206 v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd); 01207 #endif 01208 v_STRING = "Test string"; 01209 v_DOUBLE = 3.14159; 01210 v_BOOLEAN = TRUE; 01211 v_BYTE = 42; 01212 v2_BYTE = 24; 01213 #ifdef HAVE_UNIX_FD_PASSING 01214 v_UNIX_FD = 1; 01215 #endif 01216 01217 dbus_message_append_args (message, 01218 DBUS_TYPE_INT16, &v_INT16, 01219 DBUS_TYPE_UINT16, &v_UINT16, 01220 DBUS_TYPE_INT32, &v_INT32, 01221 DBUS_TYPE_UINT32, &v_UINT32, 01222 #ifdef DBUS_HAVE_INT64 01223 DBUS_TYPE_INT64, &v_INT64, 01224 DBUS_TYPE_UINT64, &v_UINT64, 01225 #endif 01226 DBUS_TYPE_STRING, &v_STRING, 01227 DBUS_TYPE_DOUBLE, &v_DOUBLE, 01228 DBUS_TYPE_BOOLEAN, &v_BOOLEAN, 01229 DBUS_TYPE_BYTE, &v_BYTE, 01230 DBUS_TYPE_BYTE, &v2_BYTE, 01231 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32, 01232 _DBUS_N_ELEMENTS (our_uint32_array), 01233 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32, 01234 _DBUS_N_ELEMENTS (our_int32_array), 01235 #ifdef DBUS_HAVE_INT64 01236 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64, 01237 _DBUS_N_ELEMENTS (our_uint64_array), 01238 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64, 01239 _DBUS_N_ELEMENTS (our_int64_array), 01240 #endif 01241 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE, 01242 _DBUS_N_ELEMENTS (our_double_array), 01243 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE, 01244 _DBUS_N_ELEMENTS (our_byte_array), 01245 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN, 01246 _DBUS_N_ELEMENTS (our_boolean_array), 01247 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, 01248 _DBUS_N_ELEMENTS (our_string_array), 01249 01250 DBUS_TYPE_INVALID); 01251 01252 i = 0; 01253 sig[i++] = DBUS_TYPE_INT16; 01254 sig[i++] = DBUS_TYPE_UINT16; 01255 sig[i++] = DBUS_TYPE_INT32; 01256 sig[i++] = DBUS_TYPE_UINT32; 01257 #ifdef DBUS_HAVE_INT64 01258 sig[i++] = DBUS_TYPE_INT64; 01259 sig[i++] = DBUS_TYPE_UINT64; 01260 #endif 01261 sig[i++] = DBUS_TYPE_STRING; 01262 sig[i++] = DBUS_TYPE_DOUBLE; 01263 sig[i++] = DBUS_TYPE_BOOLEAN; 01264 sig[i++] = DBUS_TYPE_BYTE; 01265 sig[i++] = DBUS_TYPE_BYTE; 01266 sig[i++] = DBUS_TYPE_ARRAY; 01267 sig[i++] = DBUS_TYPE_UINT32; 01268 sig[i++] = DBUS_TYPE_ARRAY; 01269 sig[i++] = DBUS_TYPE_INT32; 01270 #ifdef DBUS_HAVE_INT64 01271 sig[i++] = DBUS_TYPE_ARRAY; 01272 sig[i++] = DBUS_TYPE_UINT64; 01273 sig[i++] = DBUS_TYPE_ARRAY; 01274 sig[i++] = DBUS_TYPE_INT64; 01275 #endif 01276 sig[i++] = DBUS_TYPE_ARRAY; 01277 sig[i++] = DBUS_TYPE_DOUBLE; 01278 sig[i++] = DBUS_TYPE_ARRAY; 01279 sig[i++] = DBUS_TYPE_BYTE; 01280 sig[i++] = DBUS_TYPE_ARRAY; 01281 sig[i++] = DBUS_TYPE_BOOLEAN; 01282 sig[i++] = DBUS_TYPE_ARRAY; 01283 sig[i++] = DBUS_TYPE_STRING; 01284 01285 message_without_unix_fds = dbus_message_copy(message); 01286 _dbus_assert(message_without_unix_fds); 01287 #ifdef HAVE_UNIX_FD_PASSING 01288 dbus_message_append_args (message, 01289 DBUS_TYPE_UNIX_FD, &v_UNIX_FD, 01290 DBUS_TYPE_INVALID); 01291 sig[i++] = DBUS_TYPE_UNIX_FD; 01292 #endif 01293 sig[i++] = DBUS_TYPE_INVALID; 01294 01295 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); 01296 01297 _dbus_verbose ("HEADER\n"); 01298 _dbus_verbose_bytes_of_string (&message->header.data, 0, 01299 _dbus_string_get_length (&message->header.data)); 01300 _dbus_verbose ("BODY\n"); 01301 _dbus_verbose_bytes_of_string (&message->body, 0, 01302 _dbus_string_get_length (&message->body)); 01303 01304 _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n", 01305 sig, dbus_message_get_signature (message)); 01306 01307 s = dbus_message_get_signature (message); 01308 01309 _dbus_assert (dbus_message_has_signature (message, sig)); 01310 _dbus_assert (strcmp (s, sig) == 0); 01311 01312 verify_test_message (message); 01313 01314 copy = dbus_message_copy (message); 01315 01316 _dbus_assert (dbus_message_get_reply_serial (message) == 01317 dbus_message_get_reply_serial (copy)); 01318 _dbus_assert (message->header.padding == copy->header.padding); 01319 01320 _dbus_assert (_dbus_string_get_length (&message->header.data) == 01321 _dbus_string_get_length (©->header.data)); 01322 01323 _dbus_assert (_dbus_string_get_length (&message->body) == 01324 _dbus_string_get_length (©->body)); 01325 01326 verify_test_message (copy); 01327 01328 name1 = dbus_message_get_interface (message); 01329 name2 = dbus_message_get_interface (copy); 01330 01331 _dbus_assert (strcmp (name1, name2) == 0); 01332 01333 name1 = dbus_message_get_member (message); 01334 name2 = dbus_message_get_member (copy); 01335 01336 _dbus_assert (strcmp (name1, name2) == 0); 01337 01338 dbus_message_unref (copy); 01339 01340 /* Message loader test */ 01341 dbus_message_lock (message); 01342 loader = _dbus_message_loader_new (); 01343 01344 /* check ref/unref */ 01345 _dbus_message_loader_ref (loader); 01346 _dbus_message_loader_unref (loader); 01347 01348 /* Write the header data one byte at a time */ 01349 data = _dbus_string_get_const_data (&message->header.data); 01350 for (i = 0; i < _dbus_string_get_length (&message->header.data); i++) 01351 { 01352 DBusString *buffer; 01353 01354 _dbus_message_loader_get_buffer (loader, &buffer); 01355 _dbus_string_append_byte (buffer, data[i]); 01356 _dbus_message_loader_return_buffer (loader, buffer, 1); 01357 } 01358 01359 /* Write the body data one byte at a time */ 01360 data = _dbus_string_get_const_data (&message->body); 01361 for (i = 0; i < _dbus_string_get_length (&message->body); i++) 01362 { 01363 DBusString *buffer; 01364 01365 _dbus_message_loader_get_buffer (loader, &buffer); 01366 _dbus_string_append_byte (buffer, data[i]); 01367 _dbus_message_loader_return_buffer (loader, buffer, 1); 01368 } 01369 01370 #ifdef HAVE_UNIX_FD_PASSING 01371 { 01372 int *unix_fds; 01373 unsigned n_unix_fds; 01374 /* Write unix fd */ 01375 _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds); 01376 _dbus_assert(n_unix_fds > 0); 01377 _dbus_assert(message->n_unix_fds == 1); 01378 unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL); 01379 _dbus_assert(unix_fds[0] >= 0); 01380 _dbus_message_loader_return_unix_fds(loader, unix_fds, 1); 01381 } 01382 #endif 01383 01384 dbus_message_unref (message); 01385 01386 /* Now pop back the message */ 01387 if (!_dbus_message_loader_queue_messages (loader)) 01388 _dbus_assert_not_reached ("no memory to queue messages"); 01389 01390 if (_dbus_message_loader_get_is_corrupted (loader)) 01391 _dbus_assert_not_reached ("message loader corrupted"); 01392 01393 message = _dbus_message_loader_pop_message (loader); 01394 if (!message) 01395 _dbus_assert_not_reached ("received a NULL message"); 01396 01397 if (dbus_message_get_reply_serial (message) != 5678) 01398 _dbus_assert_not_reached ("reply serial fields differ"); 01399 01400 dbus_message_unref (message); 01401 01402 /* ovveride the serial, since it was reset by dbus_message_copy() */ 01403 dbus_message_set_serial(message_without_unix_fds, 8901); 01404 01405 dbus_message_lock (message_without_unix_fds); 01406 01407 verify_test_message (message_without_unix_fds); 01408 01409 { 01410 /* Marshal and demarshal the message. */ 01411 01412 DBusMessage *message2; 01413 DBusError error = DBUS_ERROR_INIT; 01414 char *marshalled = NULL; 01415 int len = 0; 01416 char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx"; 01417 01418 if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len)) 01419 _dbus_assert_not_reached ("failed to marshal message"); 01420 01421 _dbus_assert (len != 0); 01422 _dbus_assert (marshalled != NULL); 01423 01424 _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len); 01425 message2 = dbus_message_demarshal (marshalled, len, &error); 01426 01427 _dbus_assert (message2 != NULL); 01428 _dbus_assert (!dbus_error_is_set (&error)); 01429 verify_test_message (message2); 01430 01431 dbus_message_unref (message2); 01432 dbus_free (marshalled); 01433 01434 /* Demarshal invalid message. */ 01435 01436 message2 = dbus_message_demarshal ("invalid", 7, &error); 01437 _dbus_assert (message2 == NULL); 01438 _dbus_assert (dbus_error_is_set (&error)); 01439 dbus_error_free (&error); 01440 01441 /* Demarshal invalid (empty) message. */ 01442 01443 message2 = dbus_message_demarshal ("", 0, &error); 01444 _dbus_assert (message2 == NULL); 01445 _dbus_assert (dbus_error_is_set (&error)); 01446 dbus_error_free (&error); 01447 01448 /* Bytes needed to demarshal empty message: 0 (more) */ 01449 01450 _dbus_assert (dbus_message_demarshal_bytes_needed ("", 0) == 0); 01451 01452 /* Bytes needed to demarshal invalid message: -1 (error). */ 01453 01454 _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1); 01455 } 01456 01457 dbus_message_unref (message_without_unix_fds); 01458 _dbus_message_loader_unref (loader); 01459 01460 check_memleaks (); 01461 _dbus_check_fdleaks_leave (initial_fds); 01462 initial_fds = _dbus_check_fdleaks_enter (); 01463 01464 /* Check that we can abandon a container */ 01465 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01466 "/org/freedesktop/TestPath", 01467 "Foo.TestInterface", 01468 "Method"); 01469 01470 dbus_message_iter_init_append (message, &iter); 01471 01472 _dbus_assert (dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 01473 (DBUS_STRUCT_BEGIN_CHAR_AS_STRING 01474 DBUS_TYPE_STRING_AS_STRING 01475 DBUS_TYPE_STRING_AS_STRING 01476 DBUS_STRUCT_END_CHAR_AS_STRING), 01477 &array_iter)); 01478 _dbus_assert (dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, 01479 NULL, &struct_iter)); 01480 01481 s = "peaches"; 01482 _dbus_assert (dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, 01483 &s)); 01484 01485 /* uh-oh, error, try and unwind */ 01486 01487 dbus_message_iter_abandon_container (&array_iter, &struct_iter); 01488 dbus_message_iter_abandon_container (&array_iter, &iter); 01489 01490 dbus_message_unref (message); 01491 01492 /* Load all the sample messages from the message factory */ 01493 { 01494 DBusMessageDataIter diter; 01495 DBusMessageData mdata; 01496 int count; 01497 01498 reset_validities_seen (); 01499 01500 count = 0; 01501 _dbus_message_data_iter_init (&diter); 01502 01503 while (_dbus_message_data_iter_get_and_next (&diter, 01504 &mdata)) 01505 { 01506 if (!dbus_internal_do_not_use_try_message_data (&mdata.data, 01507 mdata.expected_validity)) 01508 { 01509 _dbus_warn ("expected validity %d and did not get it\n", 01510 mdata.expected_validity); 01511 _dbus_assert_not_reached ("message data failed"); 01512 } 01513 01514 _dbus_message_data_free (&mdata); 01515 01516 count += 1; 01517 } 01518 01519 printf ("%d sample messages tested\n", count); 01520 01521 print_validities_seen (FALSE); 01522 print_validities_seen (TRUE); 01523 } 01524 01525 check_memleaks (); 01526 _dbus_check_fdleaks_leave (initial_fds); 01527 01528 /* Now load every message in test_data_dir if we have one */ 01529 if (test_data_dir == NULL) 01530 return TRUE; 01531 01532 initial_fds = _dbus_check_fdleaks_enter (); 01533 01534 if (!dbus_internal_do_not_use_foreach_message_file (test_data_dir, 01535 (DBusForeachMessageFileFunc) 01536 dbus_internal_do_not_use_try_message_file, 01537 NULL)) 01538 _dbus_assert_not_reached ("foreach_message_file test failed"); 01539 01540 _dbus_check_fdleaks_leave (initial_fds); 01541 01542 return TRUE; 01543 } 01544 01545 #endif /* DBUS_BUILD_TESTS */