|
D-Bus
1.8.20
|
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 int our_unix_fd1; 01049 int our_unix_fd2; 01050 DBusInitialFDs *initial_fds; 01051 01052 initial_fds = _dbus_check_fdleaks_enter (); 01053 01054 /* parse with wrong signature: "uashuu" */ 01055 dbus_error_free (&error); 01056 dbus_message_iter_init (message, &iter); 01057 if (!dbus_message_iter_get_args (&iter, &error, 01058 DBUS_TYPE_UINT32, &our_uint1, 01059 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 01060 &our_string_array1, &our_string_array_len1, 01061 #ifdef HAVE_UNIX_FD_PASSING 01062 DBUS_TYPE_UNIX_FD, &our_unix_fd1, 01063 #endif 01064 DBUS_TYPE_UINT32, &our_uint2, 01065 DBUS_TYPE_UINT32, &our_uint3, 01066 DBUS_TYPE_INVALID)) 01067 { 01068 _dbus_verbose ("expected error: %s - %s\n", error.name, 01069 (error.message != NULL) ? error.message : "no message"); 01070 /* ensure array of string and unix fd not leaked */ 01071 _dbus_assert (our_string_array1 == NULL); 01072 #ifdef HAVE_UNIX_FD_PASSING 01073 _dbus_assert (our_unix_fd1 == -1); 01074 #endif 01075 } 01076 else 01077 { 01078 _dbus_warn ("error: parse with wrong signature: 'uashuu'.\n"); 01079 } 01080 01081 /* parse with wrong signature: "uashuashu" */ 01082 dbus_message_iter_init (message, &iter); 01083 dbus_error_free (&error); 01084 if (!dbus_message_iter_get_args (&iter, &error, 01085 DBUS_TYPE_UINT32, &our_uint1, 01086 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 01087 &our_string_array1, &our_string_array_len1, 01088 #ifdef HAVE_UNIX_FD_PASSING 01089 DBUS_TYPE_UNIX_FD, &our_unix_fd1, 01090 #endif 01091 DBUS_TYPE_UINT32, &our_uint2, 01092 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 01093 &our_string_array2, &our_string_array_len2, 01094 #ifdef HAVE_UNIX_FD_PASSING 01095 DBUS_TYPE_UNIX_FD, &our_unix_fd2, 01096 #endif 01097 DBUS_TYPE_UINT32, &our_uint3, 01098 DBUS_TYPE_INVALID)) 01099 { 01100 _dbus_verbose ("expected error: %s - %s\n", error.name, 01101 (error.message != NULL) ? error.message : "no message"); 01102 /* ensure array of string and unix fd not leaked */ 01103 _dbus_assert (our_string_array1 == NULL); 01104 _dbus_assert (our_string_array2 == NULL); 01105 #ifdef HAVE_UNIX_FD_PASSING 01106 _dbus_assert (our_unix_fd1 == -1); 01107 _dbus_assert (our_unix_fd2 == -1); 01108 #endif 01109 } 01110 else 01111 { 01112 _dbus_warn ("error: parse with wrong signature: 'uashuashu'.\n"); 01113 } 01114 01115 /* parse with correct signature: "uashuash" */ 01116 dbus_message_iter_init (message, &iter); 01117 dbus_error_free (&error); 01118 if (!dbus_message_iter_get_args (&iter, &error, 01119 DBUS_TYPE_UINT32, &our_uint1, 01120 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 01121 &our_string_array1, &our_string_array_len1, 01122 #ifdef HAVE_UNIX_FD_PASSING 01123 DBUS_TYPE_UNIX_FD, &our_unix_fd1, 01124 #endif 01125 DBUS_TYPE_UINT32, &our_uint2, 01126 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, 01127 &our_string_array2, &our_string_array_len2, 01128 #ifdef HAVE_UNIX_FD_PASSING 01129 DBUS_TYPE_UNIX_FD, &our_unix_fd2, 01130 #endif 01131 DBUS_TYPE_INVALID)) 01132 { 01133 _dbus_warn ("error: %s - %s\n", error.name, 01134 (error.message != NULL) ? error.message : "no message"); 01135 _dbus_assert_not_reached ("Could not get arguments"); 01136 } 01137 else 01138 { 01139 dbus_free_string_array (our_string_array1); 01140 dbus_free_string_array (our_string_array2); 01141 #ifdef HAVE_UNIX_FD_PASSING 01142 _dbus_close (our_unix_fd1, &error); 01143 _dbus_close (our_unix_fd2, &error); 01144 #endif 01145 } 01146 _dbus_check_fdleaks_leave (initial_fds); 01147 } 01148 01155 dbus_bool_t 01156 _dbus_message_test (const char *test_data_dir) 01157 { 01158 DBusMessage *message, *message_without_unix_fds; 01159 DBusMessageLoader *loader; 01160 int i; 01161 const char *data; 01162 DBusMessage *copy; 01163 const char *name1; 01164 const char *name2; 01165 const dbus_uint32_t our_uint32_array[] = 01166 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; 01167 const dbus_int32_t our_int32_array[] = 01168 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; 01169 const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array; 01170 const dbus_int32_t *v_ARRAY_INT32 = our_int32_array; 01171 const dbus_uint64_t our_uint64_array[] = 01172 { 0x12345678, 0x23456781, 0x34567812, 0x45678123 }; 01173 const dbus_int64_t our_int64_array[] = 01174 { 0x12345678, -0x23456781, 0x34567812, -0x45678123 }; 01175 const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array; 01176 const dbus_int64_t *v_ARRAY_INT64 = our_int64_array; 01177 const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" }; 01178 const char *our_string_array1[] = { "foo", "Bar", "", "Woo woo Woo woo" }; 01179 const char **v_ARRAY_STRING = our_string_array; 01180 const char **v1_ARRAY_STRING = our_string_array1; 01181 const double our_double_array[] = { 0.1234, 9876.54321, -300.0 }; 01182 const double *v_ARRAY_DOUBLE = our_double_array; 01183 const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 }; 01184 const unsigned char *v_ARRAY_BYTE = our_byte_array; 01185 const dbus_bool_t our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE }; 01186 const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array; 01187 char sig[64]; 01188 const char *s; 01189 const char *v_STRING; 01190 double v_DOUBLE; 01191 dbus_int16_t v_INT16; 01192 dbus_uint16_t v_UINT16; 01193 dbus_int32_t v_INT32; 01194 dbus_uint32_t v_UINT32; 01195 dbus_uint32_t v1_UINT32; 01196 dbus_int64_t v_INT64; 01197 dbus_uint64_t v_UINT64; 01198 unsigned char v_BYTE; 01199 unsigned char v2_BYTE; 01200 dbus_bool_t v_BOOLEAN; 01201 DBusMessageIter iter, array_iter, struct_iter; 01202 #ifdef HAVE_UNIX_FD_PASSING 01203 int v_UNIX_FD; 01204 int v1_UNIX_FD; 01205 #endif 01206 char **decomposed; 01207 DBusInitialFDs *initial_fds; 01208 01209 initial_fds = _dbus_check_fdleaks_enter (); 01210 01211 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01212 "/org/freedesktop/TestPath", 01213 "Foo.TestInterface", 01214 "TestMethod"); 01215 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); 01216 _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface", 01217 "TestMethod")); 01218 _dbus_assert (strcmp (dbus_message_get_path (message), 01219 "/org/freedesktop/TestPath") == 0); 01220 dbus_message_set_serial (message, 1234); 01221 01222 /* string length including nul byte not a multiple of 4 */ 01223 if (!dbus_message_set_sender (message, "org.foo.bar1")) 01224 _dbus_assert_not_reached ("out of memory"); 01225 01226 _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1")); 01227 dbus_message_set_reply_serial (message, 5678); 01228 01229 _dbus_verbose_bytes_of_string (&message->header.data, 0, 01230 _dbus_string_get_length (&message->header.data)); 01231 _dbus_verbose_bytes_of_string (&message->body, 0, 01232 _dbus_string_get_length (&message->body)); 01233 01234 if (!dbus_message_set_sender (message, NULL)) 01235 _dbus_assert_not_reached ("out of memory"); 01236 01237 01238 _dbus_verbose_bytes_of_string (&message->header.data, 0, 01239 _dbus_string_get_length (&message->header.data)); 01240 _dbus_verbose_bytes_of_string (&message->body, 0, 01241 _dbus_string_get_length (&message->body)); 01242 01243 01244 _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1")); 01245 _dbus_assert (dbus_message_get_serial (message) == 1234); 01246 _dbus_assert (dbus_message_get_reply_serial (message) == 5678); 01247 _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService")); 01248 01249 _dbus_assert (dbus_message_get_no_reply (message) == FALSE); 01250 dbus_message_set_no_reply (message, TRUE); 01251 _dbus_assert (dbus_message_get_no_reply (message) == TRUE); 01252 dbus_message_set_no_reply (message, FALSE); 01253 _dbus_assert (dbus_message_get_no_reply (message) == FALSE); 01254 01255 /* Set/get some header fields */ 01256 01257 if (!dbus_message_set_path (message, "/foo")) 01258 _dbus_assert_not_reached ("out of memory"); 01259 _dbus_assert (strcmp (dbus_message_get_path (message), 01260 "/foo") == 0); 01261 01262 if (!dbus_message_set_interface (message, "org.Foo")) 01263 _dbus_assert_not_reached ("out of memory"); 01264 _dbus_assert (strcmp (dbus_message_get_interface (message), 01265 "org.Foo") == 0); 01266 01267 if (!dbus_message_set_member (message, "Bar")) 01268 _dbus_assert_not_reached ("out of memory"); 01269 _dbus_assert (strcmp (dbus_message_get_member (message), 01270 "Bar") == 0); 01271 01272 /* Set/get them with longer values */ 01273 if (!dbus_message_set_path (message, "/foo/bar")) 01274 _dbus_assert_not_reached ("out of memory"); 01275 _dbus_assert (strcmp (dbus_message_get_path (message), 01276 "/foo/bar") == 0); 01277 01278 if (!dbus_message_set_interface (message, "org.Foo.Bar")) 01279 _dbus_assert_not_reached ("out of memory"); 01280 _dbus_assert (strcmp (dbus_message_get_interface (message), 01281 "org.Foo.Bar") == 0); 01282 01283 if (!dbus_message_set_member (message, "BarFoo")) 01284 _dbus_assert_not_reached ("out of memory"); 01285 _dbus_assert (strcmp (dbus_message_get_member (message), 01286 "BarFoo") == 0); 01287 01288 /* Realloc shorter again */ 01289 01290 if (!dbus_message_set_path (message, "/foo")) 01291 _dbus_assert_not_reached ("out of memory"); 01292 _dbus_assert (strcmp (dbus_message_get_path (message), 01293 "/foo") == 0); 01294 01295 if (!dbus_message_set_interface (message, "org.Foo")) 01296 _dbus_assert_not_reached ("out of memory"); 01297 _dbus_assert (strcmp (dbus_message_get_interface (message), 01298 "org.Foo") == 0); 01299 01300 if (!dbus_message_set_member (message, "Bar")) 01301 _dbus_assert_not_reached ("out of memory"); 01302 _dbus_assert (strcmp (dbus_message_get_member (message), 01303 "Bar") == 0); 01304 01305 /* Path decomposing */ 01306 dbus_message_set_path (message, NULL); 01307 dbus_message_get_path_decomposed (message, &decomposed); 01308 _dbus_assert (decomposed == NULL); 01309 dbus_free_string_array (decomposed); 01310 01311 dbus_message_set_path (message, "/"); 01312 dbus_message_get_path_decomposed (message, &decomposed); 01313 _dbus_assert (decomposed != NULL); 01314 _dbus_assert (decomposed[0] == NULL); 01315 dbus_free_string_array (decomposed); 01316 01317 dbus_message_set_path (message, "/a/b"); 01318 dbus_message_get_path_decomposed (message, &decomposed); 01319 _dbus_assert (decomposed != NULL); 01320 _dbus_assert (strcmp (decomposed[0], "a") == 0); 01321 _dbus_assert (strcmp (decomposed[1], "b") == 0); 01322 _dbus_assert (decomposed[2] == NULL); 01323 dbus_free_string_array (decomposed); 01324 01325 dbus_message_set_path (message, "/spam/eggs"); 01326 dbus_message_get_path_decomposed (message, &decomposed); 01327 _dbus_assert (decomposed != NULL); 01328 _dbus_assert (strcmp (decomposed[0], "spam") == 0); 01329 _dbus_assert (strcmp (decomposed[1], "eggs") == 0); 01330 _dbus_assert (decomposed[2] == NULL); 01331 dbus_free_string_array (decomposed); 01332 01333 dbus_message_unref (message); 01334 01335 /* Test the vararg functions */ 01336 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01337 "/org/freedesktop/TestPath", 01338 "Foo.TestInterface", 01339 "TestMethod"); 01340 dbus_message_set_serial (message, 1); 01341 dbus_message_set_reply_serial (message, 5678); 01342 01343 v_INT16 = -0x123; 01344 v_UINT16 = 0x123; 01345 v_INT32 = -0x12345678; 01346 v_UINT32 = 0x12300042; 01347 v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd); 01348 v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd); 01349 v_STRING = "Test string"; 01350 v_DOUBLE = 3.14159; 01351 v_BOOLEAN = TRUE; 01352 v_BYTE = 42; 01353 v2_BYTE = 24; 01354 #ifdef HAVE_UNIX_FD_PASSING 01355 v_UNIX_FD = 1; 01356 v1_UNIX_FD = 2; 01357 #endif 01358 01359 dbus_message_append_args (message, 01360 DBUS_TYPE_INT16, &v_INT16, 01361 DBUS_TYPE_UINT16, &v_UINT16, 01362 DBUS_TYPE_INT32, &v_INT32, 01363 DBUS_TYPE_UINT32, &v_UINT32, 01364 DBUS_TYPE_INT64, &v_INT64, 01365 DBUS_TYPE_UINT64, &v_UINT64, 01366 DBUS_TYPE_STRING, &v_STRING, 01367 DBUS_TYPE_DOUBLE, &v_DOUBLE, 01368 DBUS_TYPE_BOOLEAN, &v_BOOLEAN, 01369 DBUS_TYPE_BYTE, &v_BYTE, 01370 DBUS_TYPE_BYTE, &v2_BYTE, 01371 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32, 01372 _DBUS_N_ELEMENTS (our_uint32_array), 01373 DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32, 01374 _DBUS_N_ELEMENTS (our_int32_array), 01375 DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64, 01376 _DBUS_N_ELEMENTS (our_uint64_array), 01377 DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64, 01378 _DBUS_N_ELEMENTS (our_int64_array), 01379 DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE, 01380 _DBUS_N_ELEMENTS (our_double_array), 01381 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE, 01382 _DBUS_N_ELEMENTS (our_byte_array), 01383 DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN, 01384 _DBUS_N_ELEMENTS (our_boolean_array), 01385 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, 01386 _DBUS_N_ELEMENTS (our_string_array), 01387 01388 DBUS_TYPE_INVALID); 01389 01390 i = 0; 01391 sig[i++] = DBUS_TYPE_INT16; 01392 sig[i++] = DBUS_TYPE_UINT16; 01393 sig[i++] = DBUS_TYPE_INT32; 01394 sig[i++] = DBUS_TYPE_UINT32; 01395 sig[i++] = DBUS_TYPE_INT64; 01396 sig[i++] = DBUS_TYPE_UINT64; 01397 sig[i++] = DBUS_TYPE_STRING; 01398 sig[i++] = DBUS_TYPE_DOUBLE; 01399 sig[i++] = DBUS_TYPE_BOOLEAN; 01400 sig[i++] = DBUS_TYPE_BYTE; 01401 sig[i++] = DBUS_TYPE_BYTE; 01402 sig[i++] = DBUS_TYPE_ARRAY; 01403 sig[i++] = DBUS_TYPE_UINT32; 01404 sig[i++] = DBUS_TYPE_ARRAY; 01405 sig[i++] = DBUS_TYPE_INT32; 01406 sig[i++] = DBUS_TYPE_ARRAY; 01407 sig[i++] = DBUS_TYPE_UINT64; 01408 sig[i++] = DBUS_TYPE_ARRAY; 01409 sig[i++] = DBUS_TYPE_INT64; 01410 sig[i++] = DBUS_TYPE_ARRAY; 01411 sig[i++] = DBUS_TYPE_DOUBLE; 01412 sig[i++] = DBUS_TYPE_ARRAY; 01413 sig[i++] = DBUS_TYPE_BYTE; 01414 sig[i++] = DBUS_TYPE_ARRAY; 01415 sig[i++] = DBUS_TYPE_BOOLEAN; 01416 sig[i++] = DBUS_TYPE_ARRAY; 01417 sig[i++] = DBUS_TYPE_STRING; 01418 01419 message_without_unix_fds = dbus_message_copy(message); 01420 _dbus_assert(message_without_unix_fds); 01421 #ifdef HAVE_UNIX_FD_PASSING 01422 dbus_message_append_args (message, 01423 DBUS_TYPE_UNIX_FD, &v_UNIX_FD, 01424 DBUS_TYPE_INVALID); 01425 sig[i++] = DBUS_TYPE_UNIX_FD; 01426 #endif 01427 sig[i++] = DBUS_TYPE_INVALID; 01428 01429 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); 01430 01431 _dbus_verbose ("HEADER\n"); 01432 _dbus_verbose_bytes_of_string (&message->header.data, 0, 01433 _dbus_string_get_length (&message->header.data)); 01434 _dbus_verbose ("BODY\n"); 01435 _dbus_verbose_bytes_of_string (&message->body, 0, 01436 _dbus_string_get_length (&message->body)); 01437 01438 _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n", 01439 sig, dbus_message_get_signature (message)); 01440 01441 s = dbus_message_get_signature (message); 01442 01443 _dbus_assert (dbus_message_has_signature (message, sig)); 01444 _dbus_assert (strcmp (s, sig) == 0); 01445 01446 verify_test_message (message); 01447 01448 copy = dbus_message_copy (message); 01449 01450 _dbus_assert (dbus_message_get_reply_serial (message) == 01451 dbus_message_get_reply_serial (copy)); 01452 _dbus_assert (message->header.padding == copy->header.padding); 01453 01454 _dbus_assert (_dbus_string_get_length (&message->header.data) == 01455 _dbus_string_get_length (©->header.data)); 01456 01457 _dbus_assert (_dbus_string_get_length (&message->body) == 01458 _dbus_string_get_length (©->body)); 01459 01460 verify_test_message (copy); 01461 01462 name1 = dbus_message_get_interface (message); 01463 name2 = dbus_message_get_interface (copy); 01464 01465 _dbus_assert (strcmp (name1, name2) == 0); 01466 01467 name1 = dbus_message_get_member (message); 01468 name2 = dbus_message_get_member (copy); 01469 01470 _dbus_assert (strcmp (name1, name2) == 0); 01471 01472 dbus_message_unref (copy); 01473 01474 /* Message loader test */ 01475 dbus_message_lock (message); 01476 loader = _dbus_message_loader_new (); 01477 01478 /* check ref/unref */ 01479 _dbus_message_loader_ref (loader); 01480 _dbus_message_loader_unref (loader); 01481 01482 /* Write the header data one byte at a time */ 01483 data = _dbus_string_get_const_data (&message->header.data); 01484 for (i = 0; i < _dbus_string_get_length (&message->header.data); i++) 01485 { 01486 DBusString *buffer; 01487 01488 _dbus_message_loader_get_buffer (loader, &buffer); 01489 _dbus_string_append_byte (buffer, data[i]); 01490 _dbus_message_loader_return_buffer (loader, buffer); 01491 } 01492 01493 /* Write the body data one byte at a time */ 01494 data = _dbus_string_get_const_data (&message->body); 01495 for (i = 0; i < _dbus_string_get_length (&message->body); i++) 01496 { 01497 DBusString *buffer; 01498 01499 _dbus_message_loader_get_buffer (loader, &buffer); 01500 _dbus_string_append_byte (buffer, data[i]); 01501 _dbus_message_loader_return_buffer (loader, buffer); 01502 } 01503 01504 #ifdef HAVE_UNIX_FD_PASSING 01505 { 01506 int *unix_fds; 01507 unsigned n_unix_fds; 01508 /* Write unix fd */ 01509 _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds); 01510 _dbus_assert(n_unix_fds > 0); 01511 _dbus_assert(message->n_unix_fds == 1); 01512 unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL); 01513 _dbus_assert(unix_fds[0] >= 0); 01514 _dbus_message_loader_return_unix_fds(loader, unix_fds, 1); 01515 } 01516 #endif 01517 01518 dbus_message_unref (message); 01519 01520 /* Now pop back the message */ 01521 if (!_dbus_message_loader_queue_messages (loader)) 01522 _dbus_assert_not_reached ("no memory to queue messages"); 01523 01524 if (_dbus_message_loader_get_is_corrupted (loader)) 01525 _dbus_assert_not_reached ("message loader corrupted"); 01526 01527 message = _dbus_message_loader_pop_message (loader); 01528 if (!message) 01529 _dbus_assert_not_reached ("received a NULL message"); 01530 01531 if (dbus_message_get_reply_serial (message) != 5678) 01532 _dbus_assert_not_reached ("reply serial fields differ"); 01533 01534 dbus_message_unref (message); 01535 01536 /* ovveride the serial, since it was reset by dbus_message_copy() */ 01537 dbus_message_set_serial(message_without_unix_fds, 8901); 01538 01539 dbus_message_lock (message_without_unix_fds); 01540 01541 verify_test_message (message_without_unix_fds); 01542 01543 { 01544 /* Marshal and demarshal the message. */ 01545 01546 DBusMessage *message2; 01547 DBusError error = DBUS_ERROR_INIT; 01548 char *marshalled = NULL; 01549 int len = 0; 01550 char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx"; 01551 01552 if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len)) 01553 _dbus_assert_not_reached ("failed to marshal message"); 01554 01555 _dbus_assert (len != 0); 01556 _dbus_assert (marshalled != NULL); 01557 01558 _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len); 01559 message2 = dbus_message_demarshal (marshalled, len, &error); 01560 01561 _dbus_assert (message2 != NULL); 01562 _dbus_assert (!dbus_error_is_set (&error)); 01563 verify_test_message (message2); 01564 01565 dbus_message_unref (message2); 01566 dbus_free (marshalled); 01567 01568 /* Demarshal invalid message. */ 01569 01570 message2 = dbus_message_demarshal ("invalid", 7, &error); 01571 _dbus_assert (message2 == NULL); 01572 _dbus_assert (dbus_error_is_set (&error)); 01573 dbus_error_free (&error); 01574 01575 /* Demarshal invalid (empty) message. */ 01576 01577 message2 = dbus_message_demarshal ("", 0, &error); 01578 _dbus_assert (message2 == NULL); 01579 _dbus_assert (dbus_error_is_set (&error)); 01580 dbus_error_free (&error); 01581 01582 /* Bytes needed to demarshal empty message: 0 (more) */ 01583 01584 _dbus_assert (dbus_message_demarshal_bytes_needed ("", 0) == 0); 01585 01586 /* Bytes needed to demarshal invalid message: -1 (error). */ 01587 01588 _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1); 01589 } 01590 01591 dbus_message_unref (message_without_unix_fds); 01592 _dbus_message_loader_unref (loader); 01593 01594 check_memleaks (); 01595 _dbus_check_fdleaks_leave (initial_fds); 01596 initial_fds = _dbus_check_fdleaks_enter (); 01597 01598 /* Check that we can abandon a container */ 01599 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01600 "/org/freedesktop/TestPath", 01601 "Foo.TestInterface", 01602 "Method"); 01603 01604 dbus_message_iter_init_append (message, &iter); 01605 01606 _dbus_assert (dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 01607 (DBUS_STRUCT_BEGIN_CHAR_AS_STRING 01608 DBUS_TYPE_STRING_AS_STRING 01609 DBUS_TYPE_STRING_AS_STRING 01610 DBUS_STRUCT_END_CHAR_AS_STRING), 01611 &array_iter)); 01612 _dbus_assert (dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT, 01613 NULL, &struct_iter)); 01614 01615 s = "peaches"; 01616 _dbus_assert (dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, 01617 &s)); 01618 01619 /* uh-oh, error, try and unwind */ 01620 01621 dbus_message_iter_abandon_container (&array_iter, &struct_iter); 01622 dbus_message_iter_abandon_container (&array_iter, &iter); 01623 01624 dbus_message_unref (message); 01625 01626 /* Check we should not leak array of string or unix fd, fd.o#21259 */ 01627 message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService", 01628 "/org/freedesktop/TestPath", 01629 "Foo.TestInterface", 01630 "Method"); 01631 01632 /* signature "uashuash" */ 01633 dbus_message_append_args (message, 01634 DBUS_TYPE_UINT32, &v_UINT32, 01635 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING, 01636 _DBUS_N_ELEMENTS (our_string_array), 01637 #ifdef HAVE_UNIX_FD_PASSING 01638 DBUS_TYPE_UNIX_FD, &v_UNIX_FD, 01639 #endif 01640 DBUS_TYPE_UINT32, &v1_UINT32, 01641 DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v1_ARRAY_STRING, 01642 _DBUS_N_ELEMENTS (our_string_array1), 01643 #ifdef HAVE_UNIX_FD_PASSING 01644 DBUS_TYPE_UNIX_FD, &v1_UNIX_FD, 01645 #endif 01646 01647 DBUS_TYPE_INVALID); 01648 01649 i = 0; 01650 sig[i++] = DBUS_TYPE_UINT32; 01651 sig[i++] = DBUS_TYPE_ARRAY; 01652 sig[i++] = DBUS_TYPE_STRING; 01653 #ifdef HAVE_UNIX_FD_PASSING 01654 sig[i++] = DBUS_TYPE_UNIX_FD; 01655 #endif 01656 sig[i++] = DBUS_TYPE_UINT32; 01657 sig[i++] = DBUS_TYPE_ARRAY; 01658 sig[i++] = DBUS_TYPE_STRING; 01659 #ifdef HAVE_UNIX_FD_PASSING 01660 sig[i++] = DBUS_TYPE_UNIX_FD; 01661 #endif 01662 sig[i++] = DBUS_TYPE_INVALID; 01663 01664 _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig)); 01665 01666 verify_test_message_args_ignored (message); 01667 verify_test_message_memleak (message); 01668 01669 dbus_message_unref (message); 01670 01671 /* Load all the sample messages from the message factory */ 01672 { 01673 DBusMessageDataIter diter; 01674 DBusMessageData mdata; 01675 int count; 01676 01677 reset_validities_seen (); 01678 01679 count = 0; 01680 _dbus_message_data_iter_init (&diter); 01681 01682 while (_dbus_message_data_iter_get_and_next (&diter, 01683 &mdata)) 01684 { 01685 if (!dbus_internal_do_not_use_try_message_data (&mdata.data, 01686 mdata.expected_validity)) 01687 { 01688 _dbus_warn ("expected validity %d and did not get it\n", 01689 mdata.expected_validity); 01690 _dbus_assert_not_reached ("message data failed"); 01691 } 01692 01693 _dbus_message_data_free (&mdata); 01694 01695 count += 1; 01696 } 01697 01698 printf ("%d sample messages tested\n", count); 01699 01700 print_validities_seen (FALSE); 01701 print_validities_seen (TRUE); 01702 } 01703 01704 check_memleaks (); 01705 _dbus_check_fdleaks_leave (initial_fds); 01706 01707 /* Now load every message in test_data_dir if we have one */ 01708 if (test_data_dir == NULL) 01709 return TRUE; 01710 01711 initial_fds = _dbus_check_fdleaks_enter (); 01712 01713 if (!dbus_internal_do_not_use_foreach_message_file (test_data_dir, 01714 (DBusForeachMessageFileFunc) 01715 dbus_internal_do_not_use_try_message_file, 01716 NULL)) 01717 _dbus_assert_not_reached ("foreach_message_file test failed"); 01718 01719 _dbus_check_fdleaks_leave (initial_fds); 01720 01721 return TRUE; 01722 } 01723 01724 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
1.7.6.1