Merge branch 'my-dbus-1.2'
[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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  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   DBusMessageIter iter, array_iter, struct_iter;
998 #ifdef HAVE_UNIX_FD_PASSING
999   int v_UNIX_FD;
1000 #endif
1001
1002   message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1003                                           "/org/freedesktop/TestPath",
1004                                           "Foo.TestInterface",
1005                                           "TestMethod");
1006   _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
1007   _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface",
1008                                              "TestMethod"));
1009   _dbus_assert (strcmp (dbus_message_get_path (message),
1010                         "/org/freedesktop/TestPath") == 0);
1011   dbus_message_set_serial (message, 1234);
1012
1013   /* string length including nul byte not a multiple of 4 */
1014   if (!dbus_message_set_sender (message, "org.foo.bar1"))
1015     _dbus_assert_not_reached ("out of memory");
1016
1017   _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1"));
1018   dbus_message_set_reply_serial (message, 5678);
1019
1020   _dbus_verbose_bytes_of_string (&message->header.data, 0,
1021                                  _dbus_string_get_length (&message->header.data));
1022   _dbus_verbose_bytes_of_string (&message->body, 0,
1023                                  _dbus_string_get_length (&message->body));
1024
1025   if (!dbus_message_set_sender (message, NULL))
1026     _dbus_assert_not_reached ("out of memory");
1027
1028
1029   _dbus_verbose_bytes_of_string (&message->header.data, 0,
1030                                  _dbus_string_get_length (&message->header.data));
1031   _dbus_verbose_bytes_of_string (&message->body, 0,
1032                                  _dbus_string_get_length (&message->body));
1033
1034
1035   _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1"));
1036   _dbus_assert (dbus_message_get_serial (message) == 1234);
1037   _dbus_assert (dbus_message_get_reply_serial (message) == 5678);
1038   _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
1039
1040   _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
1041   dbus_message_set_no_reply (message, TRUE);
1042   _dbus_assert (dbus_message_get_no_reply (message) == TRUE);
1043   dbus_message_set_no_reply (message, FALSE);
1044   _dbus_assert (dbus_message_get_no_reply (message) == FALSE);
1045
1046   /* Set/get some header fields */
1047
1048   if (!dbus_message_set_path (message, "/foo"))
1049     _dbus_assert_not_reached ("out of memory");
1050   _dbus_assert (strcmp (dbus_message_get_path (message),
1051                         "/foo") == 0);
1052
1053   if (!dbus_message_set_interface (message, "org.Foo"))
1054     _dbus_assert_not_reached ("out of memory");
1055   _dbus_assert (strcmp (dbus_message_get_interface (message),
1056                         "org.Foo") == 0);
1057
1058   if (!dbus_message_set_member (message, "Bar"))
1059     _dbus_assert_not_reached ("out of memory");
1060   _dbus_assert (strcmp (dbus_message_get_member (message),
1061                         "Bar") == 0);
1062
1063   /* Set/get them with longer values */
1064   if (!dbus_message_set_path (message, "/foo/bar"))
1065     _dbus_assert_not_reached ("out of memory");
1066   _dbus_assert (strcmp (dbus_message_get_path (message),
1067                         "/foo/bar") == 0);
1068
1069   if (!dbus_message_set_interface (message, "org.Foo.Bar"))
1070     _dbus_assert_not_reached ("out of memory");
1071   _dbus_assert (strcmp (dbus_message_get_interface (message),
1072                         "org.Foo.Bar") == 0);
1073
1074   if (!dbus_message_set_member (message, "BarFoo"))
1075     _dbus_assert_not_reached ("out of memory");
1076   _dbus_assert (strcmp (dbus_message_get_member (message),
1077                         "BarFoo") == 0);
1078
1079   /* Realloc shorter again */
1080
1081   if (!dbus_message_set_path (message, "/foo"))
1082     _dbus_assert_not_reached ("out of memory");
1083   _dbus_assert (strcmp (dbus_message_get_path (message),
1084                         "/foo") == 0);
1085
1086   if (!dbus_message_set_interface (message, "org.Foo"))
1087     _dbus_assert_not_reached ("out of memory");
1088   _dbus_assert (strcmp (dbus_message_get_interface (message),
1089                         "org.Foo") == 0);
1090
1091   if (!dbus_message_set_member (message, "Bar"))
1092     _dbus_assert_not_reached ("out of memory");
1093   _dbus_assert (strcmp (dbus_message_get_member (message),
1094                         "Bar") == 0);
1095
1096   dbus_message_unref (message);
1097
1098   /* Test the vararg functions */
1099   message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1100                                           "/org/freedesktop/TestPath",
1101                                           "Foo.TestInterface",
1102                                           "TestMethod");
1103   dbus_message_set_serial (message, 1);
1104   dbus_message_set_reply_serial (message, 5678);
1105
1106   v_INT16 = -0x123;
1107   v_UINT16 = 0x123;
1108   v_INT32 = -0x12345678;
1109   v_UINT32 = 0x12300042;
1110 #ifdef DBUS_HAVE_INT64
1111   v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd);
1112   v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd);
1113 #endif
1114   v_STRING = "Test string";
1115   v_DOUBLE = 3.14159;
1116   v_BOOLEAN = TRUE;
1117   v_BYTE = 42;
1118   v2_BYTE = 24;
1119 #ifdef HAVE_UNIX_FD_PASSING
1120   v_UNIX_FD = 1;
1121 #endif
1122
1123   dbus_message_append_args (message,
1124                             DBUS_TYPE_INT16, &v_INT16,
1125                             DBUS_TYPE_UINT16, &v_UINT16,
1126                             DBUS_TYPE_INT32, &v_INT32,
1127                             DBUS_TYPE_UINT32, &v_UINT32,
1128 #ifdef DBUS_HAVE_INT64
1129                             DBUS_TYPE_INT64, &v_INT64,
1130                             DBUS_TYPE_UINT64, &v_UINT64,
1131 #endif
1132                             DBUS_TYPE_STRING, &v_STRING,
1133                             DBUS_TYPE_DOUBLE, &v_DOUBLE,
1134                             DBUS_TYPE_BOOLEAN, &v_BOOLEAN,
1135                             DBUS_TYPE_BYTE, &v_BYTE,
1136                             DBUS_TYPE_BYTE, &v2_BYTE,
1137                             DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32,
1138                             _DBUS_N_ELEMENTS (our_uint32_array),
1139                             DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32,
1140                             _DBUS_N_ELEMENTS (our_int32_array),
1141 #ifdef DBUS_HAVE_INT64
1142                             DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64,
1143                             _DBUS_N_ELEMENTS (our_uint64_array),
1144                             DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64,
1145                             _DBUS_N_ELEMENTS (our_int64_array),
1146 #endif
1147                             DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE,
1148                             _DBUS_N_ELEMENTS (our_double_array),
1149                             DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE,
1150                             _DBUS_N_ELEMENTS (our_byte_array),
1151                             DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN,
1152                             _DBUS_N_ELEMENTS (our_boolean_array),
1153                             DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING,
1154                             _DBUS_N_ELEMENTS (our_string_array),
1155
1156                             DBUS_TYPE_INVALID);
1157
1158   i = 0;
1159   sig[i++] = DBUS_TYPE_INT16;
1160   sig[i++] = DBUS_TYPE_UINT16;
1161   sig[i++] = DBUS_TYPE_INT32;
1162   sig[i++] = DBUS_TYPE_UINT32;
1163 #ifdef DBUS_HAVE_INT64
1164   sig[i++] = DBUS_TYPE_INT64;
1165   sig[i++] = DBUS_TYPE_UINT64;
1166 #endif
1167   sig[i++] = DBUS_TYPE_STRING;
1168   sig[i++] = DBUS_TYPE_DOUBLE;
1169   sig[i++] = DBUS_TYPE_BOOLEAN;
1170   sig[i++] = DBUS_TYPE_BYTE;
1171   sig[i++] = DBUS_TYPE_BYTE;
1172   sig[i++] = DBUS_TYPE_ARRAY;
1173   sig[i++] = DBUS_TYPE_UINT32;
1174   sig[i++] = DBUS_TYPE_ARRAY;
1175   sig[i++] = DBUS_TYPE_INT32;
1176 #ifdef DBUS_HAVE_INT64
1177   sig[i++] = DBUS_TYPE_ARRAY;
1178   sig[i++] = DBUS_TYPE_UINT64;
1179   sig[i++] = DBUS_TYPE_ARRAY;
1180   sig[i++] = DBUS_TYPE_INT64;
1181 #endif
1182   sig[i++] = DBUS_TYPE_ARRAY;
1183   sig[i++] = DBUS_TYPE_DOUBLE;
1184   sig[i++] = DBUS_TYPE_ARRAY;
1185   sig[i++] = DBUS_TYPE_BYTE;
1186   sig[i++] = DBUS_TYPE_ARRAY;
1187   sig[i++] = DBUS_TYPE_BOOLEAN;
1188   sig[i++] = DBUS_TYPE_ARRAY;
1189   sig[i++] = DBUS_TYPE_STRING;
1190
1191   message_without_unix_fds = dbus_message_copy(message);
1192   _dbus_assert(message_without_unix_fds);
1193 #ifdef HAVE_UNIX_FD_PASSING
1194   dbus_message_append_args (message,
1195                             DBUS_TYPE_UNIX_FD, &v_UNIX_FD,
1196                             DBUS_TYPE_INVALID);
1197   sig[i++] = DBUS_TYPE_UNIX_FD;
1198 #endif
1199   sig[i++] = DBUS_TYPE_INVALID;
1200
1201   _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
1202
1203   _dbus_verbose ("HEADER\n");
1204   _dbus_verbose_bytes_of_string (&message->header.data, 0,
1205                                  _dbus_string_get_length (&message->header.data));
1206   _dbus_verbose ("BODY\n");
1207   _dbus_verbose_bytes_of_string (&message->body, 0,
1208                                  _dbus_string_get_length (&message->body));
1209
1210   _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n",
1211                  sig, dbus_message_get_signature (message));
1212
1213   s = dbus_message_get_signature (message);
1214
1215   _dbus_assert (dbus_message_has_signature (message, sig));
1216   _dbus_assert (strcmp (s, sig) == 0);
1217
1218   verify_test_message (message);
1219
1220   copy = dbus_message_copy (message);
1221
1222   _dbus_assert (dbus_message_get_reply_serial (message) ==
1223                 dbus_message_get_reply_serial (copy));
1224   _dbus_assert (message->header.padding == copy->header.padding);
1225
1226   _dbus_assert (_dbus_string_get_length (&message->header.data) ==
1227                 _dbus_string_get_length (&copy->header.data));
1228
1229   _dbus_assert (_dbus_string_get_length (&message->body) ==
1230                 _dbus_string_get_length (&copy->body));
1231
1232   verify_test_message (copy);
1233
1234   name1 = dbus_message_get_interface (message);
1235   name2 = dbus_message_get_interface (copy);
1236
1237   _dbus_assert (strcmp (name1, name2) == 0);
1238
1239   name1 = dbus_message_get_member (message);
1240   name2 = dbus_message_get_member (copy);
1241
1242   _dbus_assert (strcmp (name1, name2) == 0);
1243
1244   dbus_message_unref (copy);
1245
1246   /* Message loader test */
1247   dbus_message_lock (message);
1248   loader = _dbus_message_loader_new ();
1249   
1250   /* check ref/unref */
1251   _dbus_message_loader_ref (loader);
1252   _dbus_message_loader_unref (loader);
1253
1254   /* Write the header data one byte at a time */
1255   data = _dbus_string_get_const_data (&message->header.data);
1256   for (i = 0; i < _dbus_string_get_length (&message->header.data); i++)
1257     {
1258       DBusString *buffer;
1259
1260       _dbus_message_loader_get_buffer (loader, &buffer);
1261       _dbus_string_append_byte (buffer, data[i]);
1262       _dbus_message_loader_return_buffer (loader, buffer, 1);
1263     }
1264
1265   /* Write the body data one byte at a time */
1266   data = _dbus_string_get_const_data (&message->body);
1267   for (i = 0; i < _dbus_string_get_length (&message->body); i++)
1268     {
1269       DBusString *buffer;
1270
1271       _dbus_message_loader_get_buffer (loader, &buffer);
1272       _dbus_string_append_byte (buffer, data[i]);
1273       _dbus_message_loader_return_buffer (loader, buffer, 1);
1274     }
1275
1276 #ifdef HAVE_UNIX_FD_PASSING
1277   {
1278     int *unix_fds;
1279     unsigned n_unix_fds;
1280     /* Write unix fd */
1281     _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds);
1282     _dbus_assert(n_unix_fds > 0);
1283     _dbus_assert(message->n_unix_fds == 1);
1284     unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL);
1285     _dbus_assert(unix_fds[0] >= 0);
1286     _dbus_message_loader_return_unix_fds(loader, unix_fds, 1);
1287   }
1288 #endif
1289
1290   dbus_message_unref (message);
1291
1292   /* Now pop back the message */
1293   if (!_dbus_message_loader_queue_messages (loader))
1294     _dbus_assert_not_reached ("no memory to queue messages");
1295
1296   if (_dbus_message_loader_get_is_corrupted (loader))
1297     _dbus_assert_not_reached ("message loader corrupted");
1298
1299   message = _dbus_message_loader_pop_message (loader);
1300   if (!message)
1301     _dbus_assert_not_reached ("received a NULL message");
1302
1303   if (dbus_message_get_reply_serial (message) != 5678)
1304     _dbus_assert_not_reached ("reply serial fields differ");
1305
1306   dbus_message_unref (message);
1307
1308   /* ovveride the serial, since it was reset by dbus_message_copy() */
1309   dbus_message_set_serial(message_without_unix_fds, 8901);
1310
1311   dbus_message_lock (message_without_unix_fds);
1312
1313   verify_test_message (message_without_unix_fds);
1314
1315     {
1316       /* Marshal and demarshal the message. */
1317
1318       DBusMessage *message2;
1319       DBusError error = DBUS_ERROR_INIT;
1320       char *marshalled = NULL;
1321       int len = 0;
1322       char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx";
1323
1324       if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len))
1325         _dbus_assert_not_reached ("failed to marshal message");
1326
1327       _dbus_assert (len != 0);
1328       _dbus_assert (marshalled != NULL);
1329
1330       _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len);
1331       message2 = dbus_message_demarshal (marshalled, len, &error);
1332
1333       _dbus_assert (message2 != NULL);
1334       _dbus_assert (!dbus_error_is_set (&error));
1335       verify_test_message (message2);
1336
1337       dbus_message_unref (message2);
1338       dbus_free (marshalled);
1339
1340       /* Demarshal invalid message. */
1341
1342       message2 = dbus_message_demarshal ("invalid", 7, &error);
1343       _dbus_assert (message2 == NULL);
1344       _dbus_assert (dbus_error_is_set (&error));
1345       dbus_error_free (&error);
1346
1347       /* Demarshal invalid (empty) message. */
1348
1349       message2 = dbus_message_demarshal ("", 0, &error);
1350       _dbus_assert (message2 == NULL);
1351       _dbus_assert (dbus_error_is_set (&error));
1352       dbus_error_free (&error);
1353
1354       /* Bytes needed to demarshal empty message: 0 (more) */
1355
1356       _dbus_assert (dbus_message_demarshal_bytes_needed ("", 0) == 0);
1357       
1358       /* Bytes needed to demarshal invalid message: -1 (error). */
1359
1360       _dbus_assert (dbus_message_demarshal_bytes_needed (garbage_header, DBUS_MINIMUM_HEADER_SIZE) == -1);
1361     }
1362
1363   dbus_message_unref (message_without_unix_fds);
1364   _dbus_message_loader_unref (loader);
1365
1366   check_memleaks ();
1367   _dbus_check_fdleaks();
1368
1369   /* Check that we can abandon a container */
1370   message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1371                                           "/org/freedesktop/TestPath",
1372                                           "Foo.TestInterface",
1373                                           "Method");
1374
1375   dbus_message_iter_init_append (message, &iter);
1376
1377   _dbus_assert (dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
1378                                                   (DBUS_STRUCT_BEGIN_CHAR_AS_STRING
1379                                                    DBUS_TYPE_STRING_AS_STRING
1380                                                    DBUS_TYPE_STRING_AS_STRING
1381                                                    DBUS_STRUCT_END_CHAR_AS_STRING),
1382                                                   &array_iter));
1383   _dbus_assert (dbus_message_iter_open_container (&array_iter, DBUS_TYPE_STRUCT,
1384                                                   NULL, &struct_iter));
1385
1386   s = "peaches";
1387   _dbus_assert (dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING,
1388                                                 &s));
1389
1390   /* uh-oh, error, try and unwind */
1391
1392   dbus_message_iter_abandon_container (&array_iter, &struct_iter);
1393   dbus_message_iter_abandon_container (&array_iter, &iter);
1394
1395   dbus_message_unref (message);
1396
1397   /* Load all the sample messages from the message factory */
1398   {
1399     DBusMessageDataIter diter;
1400     DBusMessageData mdata;
1401     int count;
1402
1403     reset_validities_seen ();
1404     
1405     count = 0;
1406     _dbus_message_data_iter_init (&diter);
1407     
1408     while (_dbus_message_data_iter_get_and_next (&diter,
1409                                                  &mdata))
1410       {
1411         if (!dbus_internal_do_not_use_try_message_data (&mdata.data,
1412                                                         mdata.expected_validity))
1413           {
1414             _dbus_warn ("expected validity %d and did not get it\n",
1415                         mdata.expected_validity);
1416             _dbus_assert_not_reached ("message data failed");
1417           }
1418
1419         _dbus_message_data_free (&mdata);
1420
1421         count += 1;
1422       }
1423
1424     printf ("%d sample messages tested\n", count);
1425
1426     print_validities_seen (FALSE);
1427     print_validities_seen (TRUE);
1428   }
1429
1430   check_memleaks ();
1431   _dbus_check_fdleaks();
1432
1433   /* Now load every message in test_data_dir if we have one */
1434   if (test_data_dir == NULL)
1435     return TRUE;
1436
1437   return dbus_internal_do_not_use_foreach_message_file (test_data_dir,
1438                                                         (DBusForeachMessageFileFunc)
1439                                                         dbus_internal_do_not_use_try_message_file,
1440                                                         NULL);  
1441 }
1442
1443 #endif /* DBUS_BUILD_TESTS */