D-Bus
1.10.12
|
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_ENABLE_EMBEDDED_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_ENABLE_EMBEDDED_TESTS */ 00080 00083 #ifdef DBUS_ENABLE_EMBEDDED_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); 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); 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); 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 dbus_int64_t v_INT64; 00758 dbus_uint64_t v_UINT64; 00759 unsigned char v_BYTE; 00760 dbus_bool_t v_BOOLEAN; 00761 00762 const dbus_int32_t *our_int_array; 00763 int len; 00764 00765 dbus_message_iter_init (message, &iter); 00766 00767 GET_AND_CHECK_STRCMP_AND_NEXT (iter, STRING, "Test string"); 00768 GET_AND_CHECK_AND_NEXT (iter, INT32, -0x12345678); 00769 GET_AND_CHECK_AND_NEXT (iter, UINT32, 0xedd1e); 00770 GET_AND_CHECK_AND_NEXT (iter, DOUBLE, 3.14159); 00771 00772 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) 00773 _dbus_assert_not_reached ("Argument type not an array"); 00774 00775 if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_DOUBLE) 00776 _dbus_assert_not_reached ("Array type not double"); 00777 00778 dbus_message_iter_recurse (&iter, &array); 00779 00780 GET_AND_CHECK_AND_NEXT (array, DOUBLE, 1.5); 00781 GET_AND_CHECK (array, DOUBLE, 2.5); 00782 00783 if (dbus_message_iter_next (&array)) 00784 _dbus_assert_not_reached ("Didn't reach end of array"); 00785 00786 if (!dbus_message_iter_next (&iter)) 00787 _dbus_assert_not_reached ("Reached end of arguments"); 00788 00789 GET_AND_CHECK_AND_NEXT (iter, BYTE, 0xF0); 00790 00791 if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) 00792 _dbus_assert_not_reached ("no array"); 00793 00794 if (dbus_message_iter_get_element_type (&iter) != DBUS_TYPE_INT32) 00795 _dbus_assert_not_reached ("Array type not int32"); 00796 00797 /* Empty array */ 00798 dbus_message_iter_recurse (&iter, &array); 00799 00800 if (dbus_message_iter_next (&array)) 00801 _dbus_assert_not_reached ("Didn't reach end of array"); 00802 00803 if (!dbus_message_iter_next (&iter)) 00804 _dbus_assert_not_reached ("Reached end of arguments"); 00805 00806 GET_AND_CHECK (iter, BYTE, 0xF0); 00807 00808 if (dbus_message_iter_next (&iter)) 00809 _dbus_assert_not_reached ("Didn't reach end of arguments"); 00810 } 00811 #endif 00812 00813 static void 00814 verify_test_message (DBusMessage *message) 00815 { 00816 DBusMessageIter iter; 00817 DBusError error = DBUS_ERROR_INIT; 00818 dbus_int16_t our_int16; 00819 dbus_uint16_t our_uint16; 00820 dbus_int32_t our_int; 00821 dbus_uint32_t our_uint; 00822 const char *our_str; 00823 double our_double; 00824 double v_DOUBLE; 00825 dbus_bool_t our_bool; 00826 unsigned char our_byte_1, our_byte_2; 00827 const dbus_uint32_t *our_uint32_array = (void*)0xdeadbeef; 00828 int our_uint32_array_len; 00829 dbus_int32_t *our_int32_array = (void*)0xdeadbeef; 00830 int our_int32_array_len; 00831 dbus_int64_t our_int64; 00832 dbus_uint64_t our_uint64; 00833 dbus_int64_t *our_uint64_array = (void*)0xdeadbeef; 00834 int our_uint64_array_len; 00835 const dbus_int64_t *our_int64_array = (void*)0xdeadbeef; 00836 int our_int64_array_len; 00837 const double *our_double_array = (void*)0xdeadbeef; 00838 int our_double_array_len; 00839 const unsigned char *our_byte_array = (void*)0xdeadbeef; 00840 int our_byte_array_len; 00841 const dbus_bool_t *our_boolean_array = (void*)0xdeadbeef; 00842 int our_boolean_array_len; 00843 char **our_string_array; 00844 int our_string_array_len; 00845 00846 dbus_message_iter_init (message, &iter); 00847 00848 if (!dbus_message_iter_get_args (&iter, &error, 00849 DBUS_TYPE_INT16, &our_int16, 00850 DBUS_TYPE_UINT16, &our_uint16, 00851 DBUS_TYPE_INT32, &our_int, 00852 DBUS_TYPE_UINT32, &our_uint, 00853 DBUS_TYPE_INT64, &our_int64, 00854 DBUS_TYPE_UINT64, &our_uint64, 00855 DBUS_TYPE_STRING, &our_str, 00856 DBUS_TYPE_DOUBLE, &our_double, 00857 DBUS_TYPE_BOOLEAN, &our_bool, 00858 DBUS_TYPE_BYTE, &our_byte_1, 00859 DBUS_TYPE_BYTE, &our_byte_2, 00860 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, 00861 &our_uint32_array, &our_uint32_array_len, 00862 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, 00863 &our_int32_array, &our_int32_array_len, 00864 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, 00865 &our_uint64_array, &our_uint64_array_len, 00866 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, 00867 &our_int64_array, &our_int64_array_len, 00868 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, 00869 &our_double_array, &our_double_array_len, 00870 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, 00871 &our_byte_array, &our_byte_array_len, 00872 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, 00873 &our_boolean_array, &our_boolean_array_len, 00874 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 00875 &our_string_array, &our_string_array_len, 00876 0)) 00877 { 00878 _dbus_warn ("error: %s - %s\n", error.name, 00879 (error.message != NULL) ? error.message : "no message"); 00880 _dbus_assert_not_reached ("Could not get arguments"); 00881 } 00882 00883 if (our_int16 != -0x123) 00884 _dbus_assert_not_reached ("16-bit integers differ!"); 00885 00886 if (our_uint16 != 0x123) 00887 _dbus_assert_not_reached ("16-bit uints differ!"); 00888 00889 if (our_int != -0x12345678) 00890 _dbus_assert_not_reached ("integers differ!"); 00891 00892 if (our_uint != 0x12300042) 00893 _dbus_assert_not_reached ("uints differ!"); 00894 00895 if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd)) 00896 _dbus_assert_not_reached ("64-bit integers differ!"); 00897 if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd)) 00898 _dbus_assert_not_reached ("64-bit unsigned integers differ!"); 00899 00900 v_DOUBLE = 3.14159; 00901 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double, v_DOUBLE)) 00902 _dbus_assert_not_reached ("doubles differ!"); 00903 00904 if (strcmp (our_str, "Test string") != 0) 00905 _dbus_assert_not_reached ("strings differ!"); 00906 00907 if (!our_bool) 00908 _dbus_assert_not_reached ("booleans differ"); 00909 00910 if (our_byte_1 != 42) 00911 _dbus_assert_not_reached ("bytes differ!"); 00912 00913 if (our_byte_2 != 24) 00914 _dbus_assert_not_reached ("bytes differ!"); 00915 00916 if (our_uint32_array_len != 4 || 00917 our_uint32_array[0] != 0x12345678 || 00918 our_uint32_array[1] != 0x23456781 || 00919 our_uint32_array[2] != 0x34567812 || 00920 our_uint32_array[3] != 0x45678123) 00921 _dbus_assert_not_reached ("uint array differs"); 00922 00923 if (our_int32_array_len != 4 || 00924 our_int32_array[0] != 0x12345678 || 00925 our_int32_array[1] != -0x23456781 || 00926 our_int32_array[2] != 0x34567812 || 00927 our_int32_array[3] != -0x45678123) 00928 _dbus_assert_not_reached ("int array differs"); 00929 00930 if (our_uint64_array_len != 4 || 00931 our_uint64_array[0] != 0x12345678 || 00932 our_uint64_array[1] != 0x23456781 || 00933 our_uint64_array[2] != 0x34567812 || 00934 our_uint64_array[3] != 0x45678123) 00935 _dbus_assert_not_reached ("uint64 array differs"); 00936 00937 if (our_int64_array_len != 4 || 00938 our_int64_array[0] != 0x12345678 || 00939 our_int64_array[1] != -0x23456781 || 00940 our_int64_array[2] != 0x34567812 || 00941 our_int64_array[3] != -0x45678123) 00942 _dbus_assert_not_reached ("int64 array differs"); 00943 00944 if (our_double_array_len != 3) 00945 _dbus_assert_not_reached ("double array had wrong length"); 00946 00947 /* On all IEEE machines (i.e. everything sane) exact equality 00948 * should be preserved over the wire 00949 */ 00950 v_DOUBLE = 0.1234; 00951 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[0], v_DOUBLE)) 00952 _dbus_assert_not_reached ("double array had wrong values"); 00953 v_DOUBLE = 9876.54321; 00954 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[1], v_DOUBLE)) 00955 _dbus_assert_not_reached ("double array had wrong values"); 00956 v_DOUBLE = -300.0; 00957 if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[2], v_DOUBLE)) 00958 _dbus_assert_not_reached ("double array had wrong values"); 00959 00960 if (our_byte_array_len != 4) 00961 _dbus_assert_not_reached ("byte array had wrong length"); 00962 00963 if (our_byte_array[0] != 'a' || 00964 our_byte_array[1] != 'b' || 00965 our_byte_array[2] != 'c' || 00966 our_byte_array[3] != 234) 00967 _dbus_assert_not_reached ("byte array had wrong values"); 00968 00969 if (our_boolean_array_len != 5) 00970 _dbus_assert_not_reached ("bool array had wrong length"); 00971 00972 if (our_boolean_array[0] != TRUE || 00973 our_boolean_array[1] != FALSE || 00974 our_boolean_array[2] != TRUE || 00975 our_boolean_array[3] != TRUE || 00976 our_boolean_array[4] != FALSE) 00977 _dbus_assert_not_reached ("bool array had wrong values"); 00978 00979 if (our_string_array_len != 4) 00980 _dbus_assert_not_reached ("string array was wrong length"); 00981 00982 if (strcmp (our_string_array[0], "Foo") != 0 || 00983 strcmp (our_string_array[1], "bar") != 0 || 00984 strcmp (our_string_array[2], "") != 0 || 00985 strcmp (our_string_array[3], "woo woo woo woo") != 0) 00986 _dbus_assert_not_reached ("string array had wrong values"); 00987 00988 dbus_free_string_array (our_string_array); 00989 00990 if (dbus_message_iter_next (&iter)) 00991 _dbus_assert_not_reached ("Didn't reach end of arguments"); 00992 } 00993 00994 static void 00995 verify_test_message_args_ignored (DBusMessage *message) 00996 { 00997 DBusMessageIter iter; 00998 DBusError error = DBUS_ERROR_INIT; 00999 dbus_uint32_t our_uint; 01000 DBusInitialFDs *initial_fds; 01001 01002 initial_fds = _dbus_check_fdleaks_enter (); 01003 01004 /* parse with empty signature: "" */ 01005 dbus_message_iter_init (message, &iter); 01006 if (!dbus_message_iter_get_args (&iter, &error, 01007 DBUS_TYPE_INVALID)) 01008 { 01009 _dbus_warn ("error: %s - %s\n", error.name, 01010 (error.message != NULL) ? error.message : "no message"); 01011 } 01012 else 01013 { 01014 _dbus_assert (!dbus_error_is_set (&error)); 01015 _dbus_verbose ("arguments ignored.\n"); 01016 } 01017 01018 /* parse with shorter signature: "u" */ 01019 dbus_message_iter_init (message, &iter); 01020 if (!dbus_message_iter_get_args (&iter, &error, 01021 DBUS_TYPE_UINT32, &our_uint, 01022 DBUS_TYPE_INVALID)) 01023 { 01024 _dbus_warn ("error: %s - %s\n", error.name, 01025 (error.message != NULL) ? error.message : "no message"); 01026 } 01027 else 01028 { 01029 _dbus_assert (!dbus_error_is_set (&error)); 01030 _dbus_verbose ("arguments ignored.\n"); 01031 } 01032 01033 _dbus_check_fdleaks_leave (initial_fds); 01034 } 01035 01036 static void 01037 verify_test_message_memleak (DBusMessage *message) 01038 { 01039 DBusMessageIter iter; 01040 DBusError error = DBUS_ERROR_INIT; 01041 dbus_uint32_t our_uint1; 01042 dbus_uint32_t our_uint2; 01043 dbus_uint32_t our_uint3; 01044 char **our_string_array1; 01045 int our_string_array_len1; 01046 char **our_string_array2; 01047 int our_string_array_len2; 01048 #ifdef HAVE_UNIX_FD_PASSING 01049 int our_unix_fd1; 01050 int our_unix_fd2; 01051 #endif 01052 DBusInitialFDs *initial_fds; 01053 01054 initial_fds = _dbus_check_fdleaks_enter (); 01055 01056 /* parse with wrong signature: "uashuu" */ 01057 dbus_error_free (&error); 01058 dbus_message_iter_init (message, &iter); 01059 if (!dbus_message_iter_get_args (&iter, &error, 01060 DBUS_TYPE_UINT32, &our_uint1, 01061 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 01062 &our_string_array1, &our_string_array_len1, 01063 #ifdef HAVE_UNIX_FD_PASSING 01064 DBUS_TYPE_UNIX_FD, &our_unix_fd1, 01065 #endif 01066 DBUS_TYPE_UINT32, &our_uint2, 01067 DBUS_TYPE_UINT32, &our_uint3, 01068 DBUS_TYPE_INVALID)) 01069 { 01070 _dbus_verbose ("expected error: %s - %s\n", error.name, 01071 (error.message != NULL) ? error.message : "no message"); 01072 /* ensure array of string and unix fd not leaked */ 01073 _dbus_assert (our_string_array1 == NULL); 01074 #ifdef HAVE_UNIX_FD_PASSING 01075 _dbus_assert (our_unix_fd1 == -1); 01076 #endif 01077 } 01078 else 01079 { 01080 _dbus_warn ("error: parse with wrong signature: 'uashuu'.\n"); 01081 } 01082 01083 /* parse with wrong signature: "uashuashu" */ 01084 dbus_message_iter_init (message, &iter); 01085 dbus_error_free (&error); 01086 if (!dbus_message_iter_get_args (&iter, &error, 01087 DBUS_TYPE_UINT32, &our_uint1, 01088 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 01089 &our_string_array1, &our_string_array_len1, 01090 #ifdef HAVE_UNIX_FD_PASSING 01091 DBUS_TYPE_UNIX_FD, &our_unix_fd1, 01092 #endif 01093 DBUS_TYPE_UINT32, &our_uint2, 01094 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 01095 &our_string_array2, &our_string_array_len2, 01096 #ifdef HAVE_UNIX_FD_PASSING 01097 DBUS_TYPE_UNIX_FD, &our_unix_fd2, 01098 #endif 01099 DBUS_TYPE_UINT32, &our_uint3, 01100 DBUS_TYPE_INVALID)) 01101 { 01102 _dbus_verbose ("expected error: %s - %s\n", error.name, 01103 (error.message != NULL) ? error.message : "no message"); 01104 /* ensure array of string and unix fd not leaked */ 01105 _dbus_assert (our_string_array1 == NULL); 01106 _dbus_assert (our_string_array2 == NULL); 01107 #ifdef HAVE_UNIX_FD_PASSING 01108 _dbus_assert (our_unix_fd1 == -1); 01109 _dbus_assert (our_unix_fd2 == -1); 01110 #endif 01111 } 01112 else 01113 { 01114 _dbus_warn ("error: parse with wrong signature: 'uashuashu'.\n"); 01115 } 01116 01117 /* parse with correct signature: "uashuash" */ 01118 dbus_message_iter_init (message, &iter); 01119 dbus_error_free (&error); 01120 if (!dbus_message_iter_get_args (&iter, &error, 01121 DBUS_TYPE_UINT32, &our_uint1, 01122 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 01123 &our_string_array1, &our_string_array_len1, 01124 #ifdef HAVE_UNIX_FD_PASSING 01125 DBUS_TYPE_UNIX_FD, &our_unix_fd1, 01126 #endif 01127 DBUS_TYPE_UINT32, &our_uint2, 01128 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 01129 &our_string_array2, &our_string_array_len2, 01130 #ifdef HAVE_UNIX_FD_PASSING 01131 DBUS_TYPE_UNIX_FD, &our_unix_fd2, 01132 #endif 01133 DBUS_TYPE_INVALID)) 01134 { 01135 _dbus_warn ("error: %s - %s\n", error.name, 01136 (error.message != NULL) ? error.message : "no message"); 01137 _dbus_assert_not_reached ("Could not get arguments"); 01138 } 01139 else 01140 { 01141 dbus_free_string_array (our_string_array1); 01142 dbus_free_string_array (our_string_array2); 01143 #ifdef HAVE_UNIX_FD_PASSING 01144 _dbus_close (our_unix_fd1, &error); 01145 _dbus_close (our_unix_fd2, &error); 01146 #endif 01147 } 01148 _dbus_check_fdleaks_leave (initial_fds); 01149 } 01150 01157 dbus_bool_t 01158 _dbus_message_test (const char *test_data_dir) 01159 { 01160 DBusMessage *message, *message_without_unix_fds; 01161 DBusMessageLoader *loader; 01162 int i; 01163 const char *data; 01164 DBusMessage *copy; 01165 const char *name1; 01166 const char *name2; 01167 const dbus_uint32_t our_uint32_array[] = 01168 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; 01169 const dbus_int32_t our_int32_array[] = 01170 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; 01171 const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array; 01172 const dbus_int32_t *v_ARRAY_INT32 = our_int32_array; 01173 const dbus_uint64_t our_uint64_array[] = 01174 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; 01175 const dbus_int64_t our_int64_array[] = 01176 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; 01177 const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array; 01178 const dbus_int64_t *v_ARRAY_INT64 = our_int64_array; 01179 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" }; 01180 const char *our_string_array1[] = { "foo", "Bar", "", "Woo woo Woo woo" }; 01181 const char **v_ARRAY_STRING = our_string_array; 01182 const char **v1_ARRAY_STRING = our_string_array1; 01183 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 }; 01184 const double *v_ARRAY_DOUBLE = our_double_array; 01185 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 }; 01186 const unsigned char *v_ARRAY_BYTE = our_byte_array; 01187 const dbus_bool_t our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE }; 01188 const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array; 01189 char sig[64]; 01190 const char *s; 01191 const char *v_STRING; 01192 double v_DOUBLE; 01193 dbus_int16_t v_INT16; 01194 dbus_uint16_t v_UINT16; 01195 dbus_int32_t v_INT32; 01196 dbus_uint32_t v_UINT32; 01197 dbus_uint32_t v1_UINT32; 01198 dbus_int64_t v_INT64; 01199 dbus_uint64_t v_UINT64; 01200 unsigned char v_BYTE; 01201 unsigned char v2_BYTE; 01202 dbus_bool_t v_BOOLEAN; 01203 DBusMessageIter iter, array_iter, struct_iter; 01204 #ifdef HAVE_UNIX_FD_PASSING 01205 int v_UNIX_FD; 01206 int v1_UNIX_FD; 01207 #endif 01208 char **decomposed; 01209 DBusInitialFDs *initial_fds; 01210 dbus_bool_t ok; 01211 char basic_types[] = DBUS_TYPE_BYTE_AS_STRING \ 01212 DBUS_TYPE_BOOLEAN_AS_STRING \ 01213 DBUS_TYPE_INT16_AS_STRING \ 01214 DBUS_TYPE_INT32_AS_STRING \ 01215 DBUS_TYPE_INT64_AS_STRING \ 01216 DBUS_TYPE_UINT16_AS_STRING \ 01217 DBUS_TYPE_UINT32_AS_STRING \ 01218 DBUS_TYPE_UINT64_AS_STRING \ 01219 DBUS_TYPE_DOUBLE_AS_STRING \ 01220 DBUS_TYPE_STRING_AS_STRING; 01221 01222 initial_fds = _dbus_check_fdleaks_enter (); 01223 01224 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01225 "/org/freedesktop/TestPath", 01226 "Foo.TestInterface", 01227 "TestMethod"); 01228 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); 01229 _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface", 01230 "TestMethod")); 01231 _dbus_assert (strcmp (dbus_message_get_path (message), 01232 "/org/freedesktop/TestPath") == 0); 01233 dbus_message_set_serial (message, 1234); 01234 01235 /* string length including nul byte not a multiple of 4 */ 01236 if (!dbus_message_set_sender (message, "org.foo.bar1")) 01237 _dbus_assert_not_reached ("out of memory"); 01238 01239 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1")); 01240 dbus_message_set_reply_serial (message, 5678); 01241 01242 _dbus_verbose_bytes_of_string (&message->header.data, 0, 01243 _dbus_string_get_length (&message->header.data)); 01244 _dbus_verbose_bytes_of_string (&message->body, 0, 01245 _dbus_string_get_length (&message->body)); 01246 01247 if (!dbus_message_set_sender (message, NULL)) 01248 _dbus_assert_not_reached ("out of memory"); 01249 01250 01251 _dbus_verbose_bytes_of_string (&message->header.data, 0, 01252 _dbus_string_get_length (&message->header.data)); 01253 _dbus_verbose_bytes_of_string (&message->body, 0, 01254 _dbus_string_get_length (&message->body)); 01255 01256 01257 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1")); 01258 _dbus_assert (dbus_message_get_serial (message) == 1234); 01259 _dbus_assert (dbus_message_get_reply_serial (message) == 5678); 01260 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); 01261 01262 _dbus_assert (dbus_message_get_no_reply (message) == FALSE); 01263 dbus_message_set_no_reply (message, TRUE); 01264 _dbus_assert (dbus_message_get_no_reply (message) == TRUE); 01265 dbus_message_set_no_reply (message, FALSE); 01266 _dbus_assert (dbus_message_get_no_reply (message) == FALSE); 01267 01268 /* Set/get some header fields */ 01269 01270 if (!dbus_message_set_path (message, "/foo")) 01271 _dbus_assert_not_reached ("out of memory"); 01272 _dbus_assert (strcmp (dbus_message_get_path (message), 01273 "/foo") == 0); 01274 01275 if (!dbus_message_set_interface (message, "org.Foo")) 01276 _dbus_assert_not_reached ("out of memory"); 01277 _dbus_assert (strcmp (dbus_message_get_interface (message), 01278 "org.Foo") == 0); 01279 01280 if (!dbus_message_set_member (message, "Bar")) 01281 _dbus_assert_not_reached ("out of memory"); 01282 _dbus_assert (strcmp (dbus_message_get_member (message), 01283 "Bar") == 0); 01284 01285 /* Set/get them with longer values */ 01286 if (!dbus_message_set_path (message, "/foo/bar")) 01287 _dbus_assert_not_reached ("out of memory"); 01288 _dbus_assert (strcmp (dbus_message_get_path (message), 01289 "/foo/bar") == 0); 01290 01291 if (!dbus_message_set_interface (message, "org.Foo.Bar")) 01292 _dbus_assert_not_reached ("out of memory"); 01293 _dbus_assert (strcmp (dbus_message_get_interface (message), 01294 "org.Foo.Bar") == 0); 01295 01296 if (!dbus_message_set_member (message, "BarFoo")) 01297 _dbus_assert_not_reached ("out of memory"); 01298 _dbus_assert (strcmp (dbus_message_get_member (message), 01299 "BarFoo") == 0); 01300 01301 /* Realloc shorter again */ 01302 01303 if (!dbus_message_set_path (message, "/foo")) 01304 _dbus_assert_not_reached ("out of memory"); 01305 _dbus_assert (strcmp (dbus_message_get_path (message), 01306 "/foo") == 0); 01307 01308 if (!dbus_message_set_interface (message, "org.Foo")) 01309 _dbus_assert_not_reached ("out of memory"); 01310 _dbus_assert (strcmp (dbus_message_get_interface (message), 01311 "org.Foo") == 0); 01312 01313 if (!dbus_message_set_member (message, "Bar")) 01314 _dbus_assert_not_reached ("out of memory"); 01315 _dbus_assert (strcmp (dbus_message_get_member (message), 01316 "Bar") == 0); 01317 01318 /* Path decomposing */ 01319 dbus_message_set_path (message, NULL); 01320 dbus_message_get_path_decomposed (message, &decomposed); 01321 _dbus_assert (decomposed == NULL); 01322 dbus_free_string_array (decomposed); 01323 01324 dbus_message_set_path (message, "/"); 01325 dbus_message_get_path_decomposed (message, &decomposed); 01326 _dbus_assert (decomposed != NULL); 01327 _dbus_assert (decomposed[0] == NULL); 01328 dbus_free_string_array (decomposed); 01329 01330 dbus_message_set_path (message, "/a/b"); 01331 dbus_message_get_path_decomposed (message, &decomposed); 01332 _dbus_assert (decomposed != NULL); 01333 _dbus_assert (strcmp (decomposed[0], "a") == 0); 01334 _dbus_assert (strcmp (decomposed[1], "b") == 0); 01335 _dbus_assert (decomposed[2] == NULL); 01336 dbus_free_string_array (decomposed); 01337 01338 dbus_message_set_path (message, "/spam/eggs"); 01339 dbus_message_get_path_decomposed (message, &decomposed); 01340 _dbus_assert (decomposed != NULL); 01341 _dbus_assert (strcmp (decomposed[0], "spam") == 0); 01342 _dbus_assert (strcmp (decomposed[1], "eggs") == 0); 01343 _dbus_assert (decomposed[2] == NULL); 01344 dbus_free_string_array (decomposed); 01345 01346 dbus_message_unref (message); 01347 01348 /* Test the vararg functions */ 01349 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01350 "/org/freedesktop/TestPath", 01351 "Foo.TestInterface", 01352 "TestMethod"); 01353 dbus_message_set_serial (message, 1); 01354 dbus_message_set_reply_serial (message, 5678); 01355 01356 v_INT16 = -0x123; 01357 v_UINT16 = 0x123; 01358 v_INT32 = -0x12345678; 01359 v_UINT32 = 0x12300042; 01360 v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd); 01361 v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd); 01362 v_STRING = "Test string"; 01363 v_DOUBLE = 3.14159; 01364 v_BOOLEAN = TRUE; 01365 v_BYTE = 42; 01366 v2_BYTE = 24; 01367 #ifdef HAVE_UNIX_FD_PASSING 01368 v_UNIX_FD = 1; 01369 v1_UNIX_FD = 2; 01370 #endif 01371 01372 dbus_message_append_args (message, 01373 DBUS_TYPE_INT16, &v_INT16, 01374 DBUS_TYPE_UINT16, &v_UINT16, 01375 DBUS_TYPE_INT32, &v_INT32, 01376 DBUS_TYPE_UINT32, &v_UINT32, 01377 DBUS_TYPE_INT64, &v_INT64, 01378 DBUS_TYPE_UINT64, &v_UINT64, 01379 DBUS_TYPE_STRING, &v_STRING, 01380 DBUS_TYPE_DOUBLE, &v_DOUBLE, 01381 DBUS_TYPE_BOOLEAN, &v_BOOLEAN, 01382 DBUS_TYPE_BYTE, &v_BYTE, 01383 DBUS_TYPE_BYTE, &v2_BYTE, 01384 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32, 01385 _DBUS_N_ELEMENTS (our_uint32_array), 01386 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32, 01387 _DBUS_N_ELEMENTS (our_int32_array), 01388 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64, 01389 _DBUS_N_ELEMENTS (our_uint64_array), 01390 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64, 01391 _DBUS_N_ELEMENTS (our_int64_array), 01392 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE, 01393 _DBUS_N_ELEMENTS (our_double_array), 01394 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE, 01395 _DBUS_N_ELEMENTS (our_byte_array), 01396 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN, 01397 _DBUS_N_ELEMENTS (our_boolean_array), 01398 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, 01399 _DBUS_N_ELEMENTS (our_string_array), 01400 01401 DBUS_TYPE_INVALID); 01402 01403 i = 0; 01404 sig[i++] = DBUS_TYPE_INT16; 01405 sig[i++] = DBUS_TYPE_UINT16; 01406 sig[i++] = DBUS_TYPE_INT32; 01407 sig[i++] = DBUS_TYPE_UINT32; 01408 sig[i++] = DBUS_TYPE_INT64; 01409 sig[i++] = DBUS_TYPE_UINT64; 01410 sig[i++] = DBUS_TYPE_STRING; 01411 sig[i++] = DBUS_TYPE_DOUBLE; 01412 sig[i++] = DBUS_TYPE_BOOLEAN; 01413 sig[i++] = DBUS_TYPE_BYTE; 01414 sig[i++] = DBUS_TYPE_BYTE; 01415 sig[i++] = DBUS_TYPE_ARRAY; 01416 sig[i++] = DBUS_TYPE_UINT32; 01417 sig[i++] = DBUS_TYPE_ARRAY; 01418 sig[i++] = DBUS_TYPE_INT32; 01419 sig[i++] = DBUS_TYPE_ARRAY; 01420 sig[i++] = DBUS_TYPE_UINT64; 01421 sig[i++] = DBUS_TYPE_ARRAY; 01422 sig[i++] = DBUS_TYPE_INT64; 01423 sig[i++] = DBUS_TYPE_ARRAY; 01424 sig[i++] = DBUS_TYPE_DOUBLE; 01425 sig[i++] = DBUS_TYPE_ARRAY; 01426 sig[i++] = DBUS_TYPE_BYTE; 01427 sig[i++] = DBUS_TYPE_ARRAY; 01428 sig[i++] = DBUS_TYPE_BOOLEAN; 01429 sig[i++] = DBUS_TYPE_ARRAY; 01430 sig[i++] = DBUS_TYPE_STRING; 01431 01432 message_without_unix_fds = dbus_message_copy(message); 01433 _dbus_assert(message_without_unix_fds); 01434 #ifdef HAVE_UNIX_FD_PASSING 01435 dbus_message_append_args (message, 01436 DBUS_TYPE_UNIX_FD, &v_UNIX_FD, 01437 DBUS_TYPE_INVALID); 01438 sig[i++] = DBUS_TYPE_UNIX_FD; 01439 #endif 01440 sig[i++] = DBUS_TYPE_INVALID; 01441 01442 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); 01443 01444 _dbus_verbose ("HEADER\n"); 01445 _dbus_verbose_bytes_of_string (&message->header.data, 0, 01446 _dbus_string_get_length (&message->header.data)); 01447 _dbus_verbose ("BODY\n"); 01448 _dbus_verbose_bytes_of_string (&message->body, 0, 01449 _dbus_string_get_length (&message->body)); 01450 01451 _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n", 01452 sig, dbus_message_get_signature (message)); 01453 01454 s = dbus_message_get_signature (message); 01455 01456 _dbus_assert (dbus_message_has_signature (message, sig)); 01457 _dbus_assert (strcmp (s, sig) == 0); 01458 01459 verify_test_message (message); 01460 01461 copy = dbus_message_copy (message); 01462 01463 _dbus_assert (dbus_message_get_reply_serial (message) == 01464 dbus_message_get_reply_serial (copy)); 01465 _dbus_assert (message->header.padding == copy->header.padding); 01466 01467 _dbus_assert (_dbus_string_get_length (&message->header.data) == 01468 _dbus_string_get_length (©->header.data)); 01469 01470 _dbus_assert (_dbus_string_get_length (&message->body) == 01471 _dbus_string_get_length (©->body)); 01472 01473 verify_test_message (copy); 01474 01475 name1 = dbus_message_get_interface (message); 01476 name2 = dbus_message_get_interface (copy); 01477 01478 _dbus_assert (strcmp (name1, name2) == 0); 01479 01480 name1 = dbus_message_get_member (message); 01481 name2 = dbus_message_get_member (copy); 01482 01483 _dbus_assert (strcmp (name1, name2) == 0); 01484 01485 dbus_message_unref (copy); 01486 01487 /* Message loader test */ 01488 dbus_message_lock (message); 01489 loader = _dbus_message_loader_new (); 01490 01491 /* check ref/unref */ 01492 _dbus_message_loader_ref (loader); 01493 _dbus_message_loader_unref (loader); 01494 01495 /* Write the header data one byte at a time */ 01496 data = _dbus_string_get_const_data (&message->header.data); 01497 for (i = 0; i < _dbus_string_get_length (&message->header.data); i++) 01498 { 01499 DBusString *buffer; 01500 01501 _dbus_message_loader_get_buffer (loader, &buffer); 01502 _dbus_string_append_byte (buffer, data[i]); 01503 _dbus_message_loader_return_buffer (loader, buffer); 01504 } 01505 01506 /* Write the body data one byte at a time */ 01507 data = _dbus_string_get_const_data (&message->body); 01508 for (i = 0; i < _dbus_string_get_length (&message->body); i++) 01509 { 01510 DBusString *buffer; 01511 01512 _dbus_message_loader_get_buffer (loader, &buffer); 01513 _dbus_string_append_byte (buffer, data[i]); 01514 _dbus_message_loader_return_buffer (loader, buffer); 01515 } 01516 01517 #ifdef HAVE_UNIX_FD_PASSING 01518 { 01519 int *unix_fds; 01520 unsigned n_unix_fds; 01521 /* Write unix fd */ 01522 _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds); 01523 _dbus_assert(n_unix_fds > 0); 01524 _dbus_assert(message->n_unix_fds == 1); 01525 unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL); 01526 _dbus_assert(unix_fds[0] >= 0); 01527 _dbus_message_loader_return_unix_fds(loader, unix_fds, 1); 01528 } 01529 #endif 01530 01531 dbus_message_unref (message); 01532 01533 /* Now pop back the message */ 01534 if (!_dbus_message_loader_queue_messages (loader)) 01535 _dbus_assert_not_reached ("no memory to queue messages"); 01536 01537 if (_dbus_message_loader_get_is_corrupted (loader)) 01538 _dbus_assert_not_reached ("message loader corrupted"); 01539 01540 message = _dbus_message_loader_pop_message (loader); 01541 if (!message) 01542 _dbus_assert_not_reached ("received a NULL message"); 01543 01544 if (dbus_message_get_reply_serial (message) != 5678) 01545 _dbus_assert_not_reached ("reply serial fields differ"); 01546 01547 dbus_message_unref (message); 01548 01549 /* ovveride the serial, since it was reset by dbus_message_copy() */ 01550 dbus_message_set_serial(message_without_unix_fds, 8901); 01551 01552 dbus_message_lock (message_without_unix_fds); 01553 01554 verify_test_message (message_without_unix_fds); 01555 01556 { 01557 /* Marshal and demarshal the message. */ 01558 01559 DBusMessage *message2; 01560 DBusError error = DBUS_ERROR_INIT; 01561 char *marshalled = NULL; 01562 int len = 0; 01563 char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx"; 01564 01565 if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len)) 01566 _dbus_assert_not_reached ("failed to marshal message"); 01567 01568 _dbus_assert (len != 0); 01569 _dbus_assert (marshalled != NULL); 01570 01571 _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len); 01572 message2 = dbus_message_demarshal (marshalled, len, &error); 01573 01574 _dbus_assert (message2 != NULL); 01575 _dbus_assert (!dbus_error_is_set (&error)); 01576 verify_test_message (message2); 01577 01578 dbus_message_unref (message2); 01579 dbus_free (marshalled); 01580 01581 /* Demarshal invalid message. */ 01582 01583 message2 = dbus_message_demarshal ("invalid", 7, &error); 01584 _dbus_assert (message2 == NULL); 01585 _dbus_assert (dbus_error_is_set (&error)); 01586 dbus_error_free (&error); 01587 01588 /* Demarshal invalid (empty) message. */ 01589 01590 message2 = dbus_message_demarshal ("", 0, &error); 01591 _dbus_assert (message2 == NULL); 01592 _dbus_assert (dbus_error_is_set (&error)); 01593 dbus_error_free (&error); 01594 01595 /* Bytes needed to demarshal empty message: 0 (more) */ 01596 01597 _dbus_assert (dbus_message_demarshal_bytes_needed ("", 0) == 0); 01598 01599 /* Bytes needed to demarshal invalid message: -1 (error). */ 01600 01601 _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1); 01602 } 01603 01604 dbus_message_unref (message_without_unix_fds); 01605 _dbus_message_loader_unref (loader); 01606 01607 check_memleaks (); 01608 _dbus_check_fdleaks_leave (initial_fds); 01609 initial_fds = _dbus_check_fdleaks_enter (); 01610 01611 /* Test enumeration of array elements */ 01612 for (i = strlen (basic_types) - 1; i > 0; i--) 01613 { 01614 DBusBasicValue val; 01615 int some; 01616 char* signature = _dbus_strdup ("?"); 01617 01618 signature[0] = basic_types[i]; 01619 s = "SomeThingToSay"; 01620 memset (&val, '\0', sizeof (val)); 01621 01622 message = dbus_message_new_method_call ("de.ende.test", 01623 "/de/ende/test", "de.ende.Test", "ArtistName"); 01624 _dbus_assert (message != NULL); 01625 dbus_message_iter_init_append (message, &iter); 01626 dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 01627 signature, &array_iter); 01628 for (some = 0; some < 3; some++) 01629 { 01630 if (basic_types[i] == DBUS_TYPE_STRING) 01631 dbus_message_iter_append_basic (&array_iter, DBUS_TYPE_STRING, &s); 01632 else 01633 dbus_message_iter_append_basic (&array_iter, basic_types[i], &val); 01634 } 01635 dbus_message_iter_close_container (&iter, &array_iter); 01636 dbus_message_iter_init (message, &iter); 01637 _dbus_assert (dbus_message_iter_get_element_count (&iter) == some); 01638 dbus_message_unref (message); 01639 dbus_free (signature); 01640 } 01641 /* Array of structs */ 01642 message = dbus_message_new_method_call ("de.ende.test", 01643 "/de/ende/test", "de.ende.Test", "ArtistName"); 01644 _dbus_assert (message != NULL); 01645 dbus_message_iter_init_append (message, &iter); 01646 dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 01647 DBUS_STRUCT_BEGIN_CHAR_AS_STRING 01648 DBUS_TYPE_STRING_AS_STRING 01649 DBUS_STRUCT_END_CHAR_AS_STRING, &array_iter); 01650 dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, 01651 NULL, &struct_iter); 01652 s = "SpamAndEggs"; 01653 dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s); 01654 dbus_message_iter_close_container (&array_iter, &struct_iter); 01655 dbus_message_iter_close_container (&iter, &array_iter); 01656 dbus_message_iter_init (message, &iter); 01657 _dbus_assert (dbus_message_iter_get_element_count (&iter) == 1); 01658 dbus_message_unref (message); 01659 check_memleaks (); 01660 01661 /* Check that we can abandon a container */ 01662 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01663 "/org/freedesktop/TestPath", 01664 "Foo.TestInterface", 01665 "Method"); 01666 01667 dbus_message_iter_init_append (message, &iter); 01668 01669 ok = dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 01670 (DBUS_STRUCT_BEGIN_CHAR_AS_STRING 01671 DBUS_TYPE_STRING_AS_STRING 01672 DBUS_TYPE_STRING_AS_STRING 01673 DBUS_STRUCT_END_CHAR_AS_STRING), 01674 &array_iter); 01675 _dbus_assert (ok); 01676 ok = dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, 01677 NULL, &struct_iter); 01678 _dbus_assert (ok); 01679 s = "peaches"; 01680 ok = dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s); 01681 _dbus_assert (ok); 01682 01683 /* uh-oh, error, try and unwind */ 01684 01685 dbus_message_iter_abandon_container (&array_iter, &struct_iter); 01686 dbus_message_iter_abandon_container (&array_iter, &iter); 01687 01688 dbus_message_unref (message); 01689 01690 /* Check we should not leak array of string or unix fd, fd.o#21259 */ 01691 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01692 "/org/freedesktop/TestPath", 01693 "Foo.TestInterface", 01694 "Method"); 01695 01696 /* signature "uashuash" */ 01697 dbus_message_append_args (message, 01698 DBUS_TYPE_UINT32, &v_UINT32, 01699 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, 01700 _DBUS_N_ELEMENTS (our_string_array), 01701 #ifdef HAVE_UNIX_FD_PASSING 01702 DBUS_TYPE_UNIX_FD, &v_UNIX_FD, 01703 #endif 01704 DBUS_TYPE_UINT32, &v1_UINT32, 01705 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v1_ARRAY_STRING, 01706 _DBUS_N_ELEMENTS (our_string_array1), 01707 #ifdef HAVE_UNIX_FD_PASSING 01708 DBUS_TYPE_UNIX_FD, &v1_UNIX_FD, 01709 #endif 01710 01711 DBUS_TYPE_INVALID); 01712 01713 i = 0; 01714 sig[i++] = DBUS_TYPE_UINT32; 01715 sig[i++] = DBUS_TYPE_ARRAY; 01716 sig[i++] = DBUS_TYPE_STRING; 01717 #ifdef HAVE_UNIX_FD_PASSING 01718 sig[i++] = DBUS_TYPE_UNIX_FD; 01719 #endif 01720 sig[i++] = DBUS_TYPE_UINT32; 01721 sig[i++] = DBUS_TYPE_ARRAY; 01722 sig[i++] = DBUS_TYPE_STRING; 01723 #ifdef HAVE_UNIX_FD_PASSING 01724 sig[i++] = DBUS_TYPE_UNIX_FD; 01725 #endif 01726 sig[i++] = DBUS_TYPE_INVALID; 01727 01728 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); 01729 01730 verify_test_message_args_ignored (message); 01731 verify_test_message_memleak (message); 01732 01733 dbus_message_unref (message); 01734 01735 /* Load all the sample messages from the message factory */ 01736 { 01737 DBusMessageDataIter diter; 01738 DBusMessageData mdata; 01739 int count; 01740 01741 reset_validities_seen (); 01742 01743 count = 0; 01744 _dbus_message_data_iter_init (&diter); 01745 01746 while (_dbus_message_data_iter_get_and_next (&diter, 01747 &mdata)) 01748 { 01749 if (!dbus_internal_do_not_use_try_message_data (&mdata.data, 01750 mdata.expected_validity)) 01751 { 01752 _dbus_warn ("expected validity %d and did not get it\n", 01753 mdata.expected_validity); 01754 _dbus_assert_not_reached ("message data failed"); 01755 } 01756 01757 _dbus_message_data_free (&mdata); 01758 01759 count += 1; 01760 } 01761 01762 printf ("%d sample messages tested\n", count); 01763 01764 print_validities_seen (FALSE); 01765 print_validities_seen (TRUE); 01766 } 01767 01768 check_memleaks (); 01769 _dbus_check_fdleaks_leave (initial_fds); 01770 01771 /* Now load every message in test_data_dir if we have one */ 01772 if (test_data_dir == NULL) 01773 return TRUE; 01774 01775 initial_fds = _dbus_check_fdleaks_enter (); 01776 01777 if (!dbus_internal_do_not_use_foreach_message_file (test_data_dir, 01778 (DBusForeachMessageFileFunc) 01779 dbus_internal_do_not_use_try_message_file, 01780 NULL)) 01781 _dbus_assert_not_reached ("foreach_message_file test failed"); 01782 01783 _dbus_check_fdleaks_leave (initial_fds); 01784 01785 return TRUE; 01786 } 01787 01788 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */