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