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