D-Bus  1.12.16
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 <config.h>
26 #include "dbus-internals.h"
27 #include "dbus-test.h"
28 #include "dbus-message-private.h"
29 #include "dbus-marshal-recursive.h"
30 #include "dbus-string.h"
31 #ifdef HAVE_UNIX_FD_PASSING
32 #include "dbus-sysdeps-unix.h"
33 #endif
34 
35 #ifdef __linux__
36 /* Necessary for the Linux-specific fd leak checking code only */
37 #include <sys/types.h>
38 #include <dirent.h>
39 #include <stdlib.h>
40 #include <errno.h>
41 #endif
42 
54 unsigned int
56 {
57 #ifdef HAVE_UNIX_FD_PASSING
58  return message->n_unix_fds;
59 #else
60  return 0;
61 #endif
62 }
63 
64 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
65 
77 static dbus_bool_t
78 dbus_message_iter_get_args (DBusMessageIter *iter,
79  DBusError *error,
80  int first_arg_type,
81  ...)
82 {
83  dbus_bool_t retval;
84  va_list var_args;
85 
86  _dbus_return_val_if_fail (iter != NULL, FALSE);
87  _dbus_return_val_if_error_is_set (error, FALSE);
88 
89  va_start (var_args, first_arg_type);
90  retval = _dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
91  va_end (var_args);
92 
93  return retval;
94 }
95 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */
96 
99 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
100 #include "dbus-test.h"
101 #include "dbus-message-factory.h"
102 #include <stdio.h>
103 #include <stdlib.h>
104 
105 static int validities_seen[DBUS_VALIDITY_LAST + _DBUS_NEGATIVE_VALIDITY_COUNT];
106 
107 static void
108 reset_validities_seen (void)
109 {
110  int i;
111  i = 0;
112  while (i < _DBUS_N_ELEMENTS (validities_seen))
113  {
114  validities_seen[i] = 0;
115  ++i;
116  }
117 }
118 
119 static void
120 record_validity_seen (DBusValidity validity)
121 {
122  validities_seen[validity + _DBUS_NEGATIVE_VALIDITY_COUNT] += 1;
123 }
124 
125 static void
126 print_validities_seen (dbus_bool_t not_seen)
127 {
128  int i;
129  i = 0;
130  while (i < _DBUS_N_ELEMENTS (validities_seen))
131  {
132  if ((i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_VALIDITY_UNKNOWN ||
133  (i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_INVALID_FOR_UNKNOWN_REASON)
134  ;
135  else if ((not_seen && validities_seen[i] == 0) ||
136  (!not_seen && validities_seen[i] > 0))
137  printf ("validity %3d seen %d times\n",
138  i - _DBUS_NEGATIVE_VALIDITY_COUNT,
139  validities_seen[i]);
140  ++i;
141  }
142 }
143 
144 static void
145 check_memleaks (void)
146 {
147  dbus_shutdown ();
148 
149  if (_dbus_get_malloc_blocks_outstanding () != 0)
150  {
151  _dbus_warn ("%d dbus_malloc blocks were not freed in %s",
152  _dbus_get_malloc_blocks_outstanding (), __FILE__);
153  _dbus_assert_not_reached ("memleaks");
154  }
155 }
156 
157 #ifdef __linux__
158 struct DBusInitialFDs {
159  fd_set set;
160 };
161 #endif
162 
163 DBusInitialFDs *
164 _dbus_check_fdleaks_enter (void)
165 {
166 #ifdef __linux__
167  DIR *d;
168  DBusInitialFDs *fds;
169 
170  /* this is plain malloc so it won't interfere with leak checking */
171  fds = malloc (sizeof (DBusInitialFDs));
172  _dbus_assert (fds != NULL);
173 
174  /* This works on Linux only */
175 
176  if ((d = opendir ("/proc/self/fd")))
177  {
178  struct dirent *de;
179 
180  while ((de = readdir(d)))
181  {
182  long l;
183  char *e = NULL;
184  int fd;
185 
186  if (de->d_name[0] == '.')
187  continue;
188 
189  errno = 0;
190  l = strtol (de->d_name, &e, 10);
191  _dbus_assert (errno == 0 && e && !*e);
192 
193  fd = (int) l;
194 
195  if (fd < 3)
196  continue;
197 
198  if (fd == dirfd (d))
199  continue;
200 
201  if (fd >= FD_SETSIZE)
202  {
203  _dbus_verbose ("FD %d unexpectedly large; cannot track whether "
204  "it is leaked\n", fd);
205  continue;
206  }
207 
208  FD_SET (fd, &fds->set);
209  }
210 
211  closedir (d);
212  }
213 
214  return fds;
215 #else
216  return NULL;
217 #endif
218 }
219 
220 void
221 _dbus_check_fdleaks_leave (DBusInitialFDs *fds)
222 {
223 #ifdef __linux__
224  DIR *d;
225 
226  /* This works on Linux only */
227 
228  if ((d = opendir ("/proc/self/fd")))
229  {
230  struct dirent *de;
231 
232  while ((de = readdir(d)))
233  {
234  long l;
235  char *e = NULL;
236  int fd;
237 
238  if (de->d_name[0] == '.')
239  continue;
240 
241  errno = 0;
242  l = strtol (de->d_name, &e, 10);
243  _dbus_assert (errno == 0 && e && !*e);
244 
245  fd = (int) l;
246 
247  if (fd < 3)
248  continue;
249 
250  if (fd == dirfd (d))
251  continue;
252 
253  if (fd >= FD_SETSIZE)
254  {
255  _dbus_verbose ("FD %d unexpectedly large; cannot track whether "
256  "it is leaked\n", fd);
257  continue;
258  }
259 
260  if (FD_ISSET (fd, &fds->set))
261  continue;
262 
263  _dbus_warn ("file descriptor %i leaked in %s.", fd, __FILE__);
264  _dbus_assert_not_reached ("fdleaks");
265  }
266 
267  closedir (d);
268  }
269 
270  free (fds);
271 #else
272  _dbus_assert (fds == NULL);
273 #endif
274 }
275 
276 static dbus_bool_t
277 check_have_valid_message (DBusMessageLoader *loader)
278 {
279  DBusMessage *message;
280  dbus_bool_t retval;
281 
282  message = NULL;
283  retval = FALSE;
284 
286  {
287  _dbus_warn ("loader corrupted on message that was expected to be valid; invalid reason %d",
288  loader->corruption_reason);
289  goto failed;
290  }
291 
292  message = _dbus_message_loader_pop_message (loader);
293  if (message == NULL)
294  {
295  _dbus_warn ("didn't load message that was expected to be valid (message not popped)");
296  goto failed;
297  }
298 
299  if (_dbus_string_get_length (&loader->data) > 0)
300  {
301  _dbus_warn ("had leftover bytes from expected-to-be-valid single message");
302  goto failed;
303  }
304 
305 #if 0
306  /* FIXME */
307  /* Verify that we're able to properly deal with the message.
308  * For example, this would detect improper handling of messages
309  * in nonstandard byte order.
310  */
311  if (!check_message_handling (message))
312  goto failed;
313 #endif
314 
315  record_validity_seen (DBUS_VALID);
316 
317  retval = TRUE;
318 
319  failed:
320  if (message)
321  dbus_message_unref (message);
322 
323  return retval;
324 }
325 
326 static dbus_bool_t
327 check_invalid_message (DBusMessageLoader *loader,
328  DBusValidity expected_validity)
329 {
330  dbus_bool_t retval;
331 
332  retval = FALSE;
333 
335  {
336  _dbus_warn ("loader not corrupted on message that was expected to be invalid");
337  goto failed;
338  }
339 
340  record_validity_seen (loader->corruption_reason);
341 
342  if (expected_validity != DBUS_INVALID_FOR_UNKNOWN_REASON &&
343  loader->corruption_reason != expected_validity)
344  {
345  _dbus_warn ("expected message to be corrupted for reason %d and was corrupted for %d instead",
346  expected_validity, loader->corruption_reason);
347  goto failed;
348  }
349 
350  retval = TRUE;
351 
352  failed:
353  return retval;
354 }
355 
356 static dbus_bool_t
357 check_incomplete_message (DBusMessageLoader *loader)
358 {
359  DBusMessage *message;
360  dbus_bool_t retval;
361 
362  message = NULL;
363  retval = FALSE;
364 
366  {
367  _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete), corruption reason %d",
368  loader->corruption_reason);
369  goto failed;
370  }
371 
372  message = _dbus_message_loader_pop_message (loader);
373  if (message != NULL)
374  {
375  _dbus_warn ("loaded message that was expected to be incomplete");
376  goto failed;
377  }
378 
379  record_validity_seen (DBUS_VALID_BUT_INCOMPLETE);
380  retval = TRUE;
381 
382  failed:
383  if (message)
384  dbus_message_unref (message);
385  return retval;
386 }
387 
388 static dbus_bool_t
389 check_loader_results (DBusMessageLoader *loader,
390  DBusValidity expected_validity)
391 {
393  _dbus_assert_not_reached ("no memory to queue messages");
394 
395  if (expected_validity == DBUS_VALID)
396  return check_have_valid_message (loader);
397  else if (expected_validity == DBUS_VALID_BUT_INCOMPLETE)
398  return check_incomplete_message (loader);
399  else if (expected_validity == DBUS_VALIDITY_UNKNOWN)
400  {
401  /* here we just know we didn't segfault and that was the
402  * only test. Also, we record that we got coverage
403  * for the validity reason.
404  */
406  record_validity_seen (loader->corruption_reason);
407 
408  return TRUE;
409  }
410  else
411  return check_invalid_message (loader, expected_validity);
412 }
413 
422 dbus_internal_do_not_use_load_message_file (const DBusString *filename,
423  DBusString *data)
424 {
425  dbus_bool_t retval;
426  DBusError error = DBUS_ERROR_INIT;
427 
428  retval = FALSE;
429 
430  _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
431  if (!_dbus_file_get_contents (data, filename, &error))
432  {
433  _dbus_warn ("Could not load message file %s: %s",
434  _dbus_string_get_const_data (filename),
435  error.message);
436  dbus_error_free (&error);
437  goto failed;
438  }
439 
440  retval = TRUE;
441 
442  failed:
443 
444  return retval;
445 }
446 
456 dbus_internal_do_not_use_try_message_file (const DBusString *filename,
457  DBusValidity expected_validity)
458 {
459  DBusString data;
460  dbus_bool_t retval;
461 
462  retval = FALSE;
463 
464  if (!_dbus_string_init (&data))
465  _dbus_assert_not_reached ("could not allocate string");
466 
467  if (!dbus_internal_do_not_use_load_message_file (filename, &data))
468  goto failed;
469 
470  retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity);
471 
472  failed:
473 
474  if (!retval)
475  {
476  if (_dbus_string_get_length (&data) > 0)
478  _dbus_string_get_length (&data));
479 
480  _dbus_warn ("Failed message loader test on %s",
481  _dbus_string_get_const_data (filename));
482  }
483 
484  _dbus_string_free (&data);
485 
486  return retval;
487 }
488 
498 dbus_internal_do_not_use_try_message_data (const DBusString *data,
499  DBusValidity expected_validity)
500 {
501  DBusMessageLoader *loader;
502  dbus_bool_t retval;
503  int len;
504  int i;
505 
506  loader = NULL;
507  retval = FALSE;
508 
509  /* Write the data one byte at a time */
510 
511  loader = _dbus_message_loader_new ();
512  if (loader == NULL)
513  goto failed;
514 
515  /* check some trivial loader functions */
516  _dbus_message_loader_ref (loader);
518 
519  len = _dbus_string_get_length (data);
520  for (i = 0; i < len; i++)
521  {
522  DBusString *buffer;
523 
524  _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
525  if (!_dbus_string_append_byte (buffer,
526  _dbus_string_get_byte (data, i)))
527  goto failed;
528  _dbus_message_loader_return_buffer (loader, buffer);
529  }
530 
531  if (!check_loader_results (loader, expected_validity))
532  goto failed;
533 
535  loader = NULL;
536 
537  /* Write the data all at once */
538 
539  loader = _dbus_message_loader_new ();
540  if (loader == NULL)
541  goto failed;
542 
543  {
544  DBusString *buffer;
545 
546  _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
547  if (!_dbus_string_copy (data, 0, buffer,
548  _dbus_string_get_length (buffer)))
549  goto failed;
550  _dbus_message_loader_return_buffer (loader, buffer);
551  }
552 
553  if (!check_loader_results (loader, expected_validity))
554  goto failed;
555 
557  loader = NULL;
558 
559  /* Write the data 2 bytes at a time */
560 
561  loader = _dbus_message_loader_new ();
562  if (loader == NULL)
563  goto failed;
564 
565  len = _dbus_string_get_length (data);
566  for (i = 0; i < len; i += 2)
567  {
568  DBusString *buffer;
569 
570  _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
571  if (!_dbus_string_append_byte (buffer,
572  _dbus_string_get_byte (data, i)))
573  goto failed;
574 
575  if ((i+1) < len)
576  {
577  if (!_dbus_string_append_byte (buffer,
578  _dbus_string_get_byte (data, i+1)))
579  goto failed;
580  }
581 
582  _dbus_message_loader_return_buffer (loader, buffer);
583  }
584 
585  if (!check_loader_results (loader, expected_validity))
586  goto failed;
587 
589  loader = NULL;
590 
591  retval = TRUE;
592 
593  failed:
594 
595  if (loader)
597 
598  return retval;
599 }
600 
601 static dbus_bool_t
602 process_test_subdir (const DBusString *test_base_dir,
603  const char *subdir,
604  DBusValidity expected_validity,
605  DBusForeachMessageFileFunc function,
606  void *user_data)
607 {
608  DBusString test_directory;
609  DBusString filename;
610  DBusDirIter *dir;
611  dbus_bool_t retval;
612  DBusError error = DBUS_ERROR_INIT;
613 
614  retval = FALSE;
615  dir = NULL;
616 
617  if (!_dbus_string_init (&test_directory))
618  _dbus_assert_not_reached ("didn't allocate test_directory");
619 
620  _dbus_string_init_const (&filename, subdir);
621 
622  if (!_dbus_string_copy (test_base_dir, 0,
623  &test_directory, 0))
624  _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
625 
626  if (!_dbus_concat_dir_and_file (&test_directory, &filename))
627  _dbus_assert_not_reached ("couldn't allocate full path");
628 
629  _dbus_string_free (&filename);
630  if (!_dbus_string_init (&filename))
631  _dbus_assert_not_reached ("didn't allocate filename string");
632 
633  dir = _dbus_directory_open (&test_directory, &error);
634  if (dir == NULL)
635  {
636  _dbus_warn ("Could not open %s: %s",
637  _dbus_string_get_const_data (&test_directory),
638  error.message);
639  dbus_error_free (&error);
640  goto failed;
641  }
642 
643  printf ("Testing %s:\n", subdir);
644 
645  next:
646  while (_dbus_directory_get_next_file (dir, &filename, &error))
647  {
648  DBusString full_path;
649 
650  if (!_dbus_string_init (&full_path))
651  _dbus_assert_not_reached ("couldn't init string");
652 
653  if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
654  _dbus_assert_not_reached ("couldn't copy dir to full_path");
655 
656  if (!_dbus_concat_dir_and_file (&full_path, &filename))
657  _dbus_assert_not_reached ("couldn't concat file to dir");
658 
659  if (_dbus_string_ends_with_c_str (&filename, ".message-raw"))
660  ;
661  else
662  {
663  if (_dbus_string_ends_with_c_str (&filename, ".message"))
664  {
665  printf ("SKIP: Could not load %s, message builder language no longer supported\n",
666  _dbus_string_get_const_data (&filename));
667  }
668 
669  _dbus_verbose ("Skipping non-.message file %s\n",
670  _dbus_string_get_const_data (&filename));
671  _dbus_string_free (&full_path);
672  goto next;
673  }
674 
675  printf (" %s\n",
676  _dbus_string_get_const_data (&filename));
677 
678  if (! (*function) (&full_path,
679  expected_validity, user_data))
680  {
681  _dbus_string_free (&full_path);
682  goto failed;
683  }
684  else
685  _dbus_string_free (&full_path);
686  }
687 
688  if (dbus_error_is_set (&error))
689  {
690  _dbus_warn ("Could not get next file in %s: %s",
691  _dbus_string_get_const_data (&test_directory),
692  error.message);
693  dbus_error_free (&error);
694  goto failed;
695  }
696 
697  retval = TRUE;
698 
699  failed:
700 
701  if (dir)
702  _dbus_directory_close (dir);
703  _dbus_string_free (&test_directory);
704  _dbus_string_free (&filename);
705 
706  return retval;
707 }
708 
719 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir,
720  DBusForeachMessageFileFunc func,
721  void *user_data)
722 {
723  DBusString test_directory;
724  dbus_bool_t retval;
725 
726  retval = FALSE;
727 
728  _dbus_string_init_const (&test_directory, test_data_dir);
729 
730  if (!process_test_subdir (&test_directory, "valid-messages",
731  DBUS_VALID, func, user_data))
732  goto failed;
733 
734  check_memleaks ();
735 
736  if (!process_test_subdir (&test_directory, "invalid-messages",
737  DBUS_INVALID_FOR_UNKNOWN_REASON, func, user_data))
738  goto failed;
739 
740  check_memleaks ();
741 
742  if (!process_test_subdir (&test_directory, "incomplete-messages",
743  DBUS_VALID_BUT_INCOMPLETE, func, user_data))
744  goto failed;
745 
746  check_memleaks ();
747 
748  retval = TRUE;
749 
750  failed:
751 
752  _dbus_string_free (&test_directory);
753 
754  return retval;
755 }
756 
757 #if 0
758 #define GET_AND_CHECK(iter, typename, literal) \
759  do { \
760  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \
761  _dbus_assert_not_reached ("got wrong argument type from message iter"); \
762  dbus_message_iter_get_basic (&iter, &v_##typename); \
763  if (v_##typename != literal) \
764  _dbus_assert_not_reached ("got wrong value from message iter"); \
765  } while (0)
766 
767 #define GET_AND_CHECK_STRCMP(iter, typename, literal) \
768  do { \
769  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \
770  _dbus_assert_not_reached ("got wrong argument type from message iter"); \
771  dbus_message_iter_get_basic (&iter, &v_##typename); \
772  if (strcmp (v_##typename, literal) != 0) \
773  _dbus_assert_not_reached ("got wrong value from message iter"); \
774  } while (0)
775 
776 #define GET_AND_CHECK_AND_NEXT(iter, typename, literal) \
777  do { \
778  GET_AND_CHECK(iter, typename, literal); \
779  if (!dbus_message_iter_next (&iter)) \
780  _dbus_assert_not_reached ("failed to move iter to next"); \
781  } while (0)
782 
783 #define GET_AND_CHECK_STRCMP_AND_NEXT(iter, typename, literal) \
784  do { \
785  GET_AND_CHECK_STRCMP(iter, typename, literal); \
786  if (!dbus_message_iter_next (&iter)) \
787  _dbus_assert_not_reached ("failed to move iter to next"); \
788  } while (0)
789 
790 static void
791 message_iter_test (DBusMessage *message)
792 {
793  DBusMessageIter iter, array, array2;
794  const char *v_STRING;
795  double v_DOUBLE;
796  dbus_int16_t v_INT16;
797  dbus_uint16_t v_UINT16;
798  dbus_int32_t v_INT32;
799  dbus_uint32_t v_UINT32;
800  dbus_int64_t v_INT64;
801  dbus_uint64_t v_UINT64;
802  unsigned char v_BYTE;
803  dbus_bool_t v_BOOLEAN;
804 
805  const dbus_int32_t *our_int_array;
806  int len;
807 
808  dbus_message_iter_init (message, &iter);
809 
810  GET_AND_CHECK_STRCMP_AND_NEXT (iter, STRING, "Test string");
811  GET_AND_CHECK_AND_NEXT (iter, INT32, -0x12345678);
812  GET_AND_CHECK_AND_NEXT (iter, UINT32, 0xedd1e);
813  GET_AND_CHECK_AND_NEXT (iter, DOUBLE, 3.14159);
814 
816  _dbus_assert_not_reached ("Argument type not an array");
817 
819  _dbus_assert_not_reached ("Array type not double");
820 
821  dbus_message_iter_recurse (&iter, &array);
822 
823  GET_AND_CHECK_AND_NEXT (array, DOUBLE, 1.5);
824  GET_AND_CHECK (array, DOUBLE, 2.5);
825 
826  if (dbus_message_iter_next (&array))
827  _dbus_assert_not_reached ("Didn't reach end of array");
828 
829  if (!dbus_message_iter_next (&iter))
830  _dbus_assert_not_reached ("Reached end of arguments");
831 
832  GET_AND_CHECK_AND_NEXT (iter, BYTE, 0xF0);
833 
835  _dbus_assert_not_reached ("no array");
836 
838  _dbus_assert_not_reached ("Array type not int32");
839 
840  /* Empty array */
841  dbus_message_iter_recurse (&iter, &array);
842 
843  if (dbus_message_iter_next (&array))
844  _dbus_assert_not_reached ("Didn't reach end of array");
845 
846  if (!dbus_message_iter_next (&iter))
847  _dbus_assert_not_reached ("Reached end of arguments");
848 
849  GET_AND_CHECK (iter, BYTE, 0xF0);
850 
851  if (dbus_message_iter_next (&iter))
852  _dbus_assert_not_reached ("Didn't reach end of arguments");
853 }
854 #endif
855 
856 static void
857 verify_test_message (DBusMessage *message)
858 {
859  DBusMessageIter iter;
860  DBusError error = DBUS_ERROR_INIT;
861  dbus_int16_t our_int16;
862  dbus_uint16_t our_uint16;
863  dbus_int32_t our_int;
864  dbus_uint32_t our_uint;
865  const char *our_str;
866  double our_double;
867  double v_DOUBLE;
868  dbus_bool_t our_bool;
869  unsigned char our_byte_1, our_byte_2;
870  const dbus_uint32_t *our_uint32_array = (void*)0xdeadbeef;
871  int our_uint32_array_len;
872  dbus_int32_t *our_int32_array = (void*)0xdeadbeef;
873  int our_int32_array_len;
874  dbus_int64_t our_int64;
875  dbus_uint64_t our_uint64;
876  dbus_int64_t *our_uint64_array = (void*)0xdeadbeef;
877  int our_uint64_array_len;
878  const dbus_int64_t *our_int64_array = (void*)0xdeadbeef;
879  int our_int64_array_len;
880  const double *our_double_array = (void*)0xdeadbeef;
881  int our_double_array_len;
882  const unsigned char *our_byte_array = (void*)0xdeadbeef;
883  int our_byte_array_len;
884  const dbus_bool_t *our_boolean_array = (void*)0xdeadbeef;
885  int our_boolean_array_len;
886  char **our_string_array;
887  int our_string_array_len;
888 
889  dbus_message_iter_init (message, &iter);
890 
891  if (!dbus_message_iter_get_args (&iter, &error,
892  DBUS_TYPE_INT16, &our_int16,
893  DBUS_TYPE_UINT16, &our_uint16,
894  DBUS_TYPE_INT32, &our_int,
895  DBUS_TYPE_UINT32, &our_uint,
896  DBUS_TYPE_INT64, &our_int64,
897  DBUS_TYPE_UINT64, &our_uint64,
898  DBUS_TYPE_STRING, &our_str,
899  DBUS_TYPE_DOUBLE, &our_double,
900  DBUS_TYPE_BOOLEAN, &our_bool,
901  DBUS_TYPE_BYTE, &our_byte_1,
902  DBUS_TYPE_BYTE, &our_byte_2,
904  &our_uint32_array, &our_uint32_array_len,
906  &our_int32_array, &our_int32_array_len,
908  &our_uint64_array, &our_uint64_array_len,
910  &our_int64_array, &our_int64_array_len,
912  &our_double_array, &our_double_array_len,
914  &our_byte_array, &our_byte_array_len,
916  &our_boolean_array, &our_boolean_array_len,
918  &our_string_array, &our_string_array_len,
919  0))
920  {
921  _dbus_warn ("error: %s - %s", error.name,
922  (error.message != NULL) ? error.message : "no message");
923  _dbus_assert_not_reached ("Could not get arguments");
924  }
925 
926  if (our_int16 != -0x123)
927  _dbus_assert_not_reached ("16-bit integers differ!");
928 
929  if (our_uint16 != 0x123)
930  _dbus_assert_not_reached ("16-bit uints differ!");
931 
932  if (our_int != -0x12345678)
933  _dbus_assert_not_reached ("integers differ!");
934 
935  if (our_uint != 0x12300042)
936  _dbus_assert_not_reached ("uints differ!");
937 
938  if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd))
939  _dbus_assert_not_reached ("64-bit integers differ!");
940  if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd))
941  _dbus_assert_not_reached ("64-bit unsigned integers differ!");
942 
943  v_DOUBLE = 3.14159;
944  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double, v_DOUBLE))
945  _dbus_assert_not_reached ("doubles differ!");
946 
947  if (strcmp (our_str, "Test string") != 0)
948  _dbus_assert_not_reached ("strings differ!");
949 
950  if (!our_bool)
951  _dbus_assert_not_reached ("booleans differ");
952 
953  if (our_byte_1 != 42)
954  _dbus_assert_not_reached ("bytes differ!");
955 
956  if (our_byte_2 != 24)
957  _dbus_assert_not_reached ("bytes differ!");
958 
959  if (our_uint32_array_len != 4 ||
960  our_uint32_array[0] != 0x12345678 ||
961  our_uint32_array[1] != 0x23456781 ||
962  our_uint32_array[2] != 0x34567812 ||
963  our_uint32_array[3] != 0x45678123)
964  _dbus_assert_not_reached ("uint array differs");
965 
966  if (our_int32_array_len != 4 ||
967  our_int32_array[0] != 0x12345678 ||
968  our_int32_array[1] != -0x23456781 ||
969  our_int32_array[2] != 0x34567812 ||
970  our_int32_array[3] != -0x45678123)
971  _dbus_assert_not_reached ("int array differs");
972 
973  if (our_uint64_array_len != 4 ||
974  our_uint64_array[0] != 0x12345678 ||
975  our_uint64_array[1] != 0x23456781 ||
976  our_uint64_array[2] != 0x34567812 ||
977  our_uint64_array[3] != 0x45678123)
978  _dbus_assert_not_reached ("uint64 array differs");
979 
980  if (our_int64_array_len != 4 ||
981  our_int64_array[0] != 0x12345678 ||
982  our_int64_array[1] != -0x23456781 ||
983  our_int64_array[2] != 0x34567812 ||
984  our_int64_array[3] != -0x45678123)
985  _dbus_assert_not_reached ("int64 array differs");
986 
987  if (our_double_array_len != 3)
988  _dbus_assert_not_reached ("double array had wrong length");
989 
990  /* On all IEEE machines (i.e. everything sane) exact equality
991  * should be preserved over the wire
992  */
993  v_DOUBLE = 0.1234;
994  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[0], v_DOUBLE))
995  _dbus_assert_not_reached ("double array had wrong values");
996  v_DOUBLE = 9876.54321;
997  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[1], v_DOUBLE))
998  _dbus_assert_not_reached ("double array had wrong values");
999  v_DOUBLE = -300.0;
1000  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[2], v_DOUBLE))
1001  _dbus_assert_not_reached ("double array had wrong values");
1002 
1003  if (our_byte_array_len != 4)
1004  _dbus_assert_not_reached ("byte array had wrong length");
1005 
1006  if (our_byte_array[0] != 'a' ||
1007  our_byte_array[1] != 'b' ||
1008  our_byte_array[2] != 'c' ||
1009  our_byte_array[3] != 234)
1010  _dbus_assert_not_reached ("byte array had wrong values");
1011 
1012  if (our_boolean_array_len != 5)
1013  _dbus_assert_not_reached ("bool array had wrong length");
1014 
1015  if (our_boolean_array[0] != TRUE ||
1016  our_boolean_array[1] != FALSE ||
1017  our_boolean_array[2] != TRUE ||
1018  our_boolean_array[3] != TRUE ||
1019  our_boolean_array[4] != FALSE)
1020  _dbus_assert_not_reached ("bool array had wrong values");
1021 
1022  if (our_string_array_len != 4)
1023  _dbus_assert_not_reached ("string array was wrong length");
1024 
1025  if (strcmp (our_string_array[0], "Foo") != 0 ||
1026  strcmp (our_string_array[1], "bar") != 0 ||
1027  strcmp (our_string_array[2], "") != 0 ||
1028  strcmp (our_string_array[3], "woo woo woo woo") != 0)
1029  _dbus_assert_not_reached ("string array had wrong values");
1030 
1031  dbus_free_string_array (our_string_array);
1032 
1033  if (dbus_message_iter_next (&iter))
1034  _dbus_assert_not_reached ("Didn't reach end of arguments");
1035 }
1036 
1037 static void
1038 verify_test_message_args_ignored (DBusMessage *message)
1039 {
1040  DBusMessageIter iter;
1041  DBusError error = DBUS_ERROR_INIT;
1042  dbus_uint32_t our_uint;
1043  DBusInitialFDs *initial_fds;
1044 
1045  initial_fds = _dbus_check_fdleaks_enter ();
1046 
1047  /* parse with empty signature: "" */
1048  dbus_message_iter_init (message, &iter);
1049  if (!dbus_message_iter_get_args (&iter, &error,
1051  {
1052  _dbus_warn ("error: %s - %s", error.name,
1053  (error.message != NULL) ? error.message : "no message");
1054  }
1055  else
1056  {
1057  _dbus_assert (!dbus_error_is_set (&error));
1058  _dbus_verbose ("arguments ignored.\n");
1059  }
1060 
1061  /* parse with shorter signature: "u" */
1062  dbus_message_iter_init (message, &iter);
1063  if (!dbus_message_iter_get_args (&iter, &error,
1064  DBUS_TYPE_UINT32, &our_uint,
1066  {
1067  _dbus_warn ("error: %s - %s", error.name,
1068  (error.message != NULL) ? error.message : "no message");
1069  }
1070  else
1071  {
1072  _dbus_assert (!dbus_error_is_set (&error));
1073  _dbus_verbose ("arguments ignored.\n");
1074  }
1075 
1076  _dbus_check_fdleaks_leave (initial_fds);
1077 }
1078 
1079 static void
1080 verify_test_message_memleak (DBusMessage *message)
1081 {
1082  DBusMessageIter iter;
1083  DBusError error = DBUS_ERROR_INIT;
1084  dbus_uint32_t our_uint1;
1085  dbus_uint32_t our_uint2;
1086  dbus_uint32_t our_uint3;
1087  char **our_string_array1;
1088  int our_string_array_len1;
1089  char **our_string_array2;
1090  int our_string_array_len2;
1091 #ifdef HAVE_UNIX_FD_PASSING
1092  int our_unix_fd1;
1093  int our_unix_fd2;
1094 #endif
1095  DBusInitialFDs *initial_fds;
1096 
1097  initial_fds = _dbus_check_fdleaks_enter ();
1098 
1099  /* parse with wrong signature: "uashuu" */
1100  dbus_error_free (&error);
1101  dbus_message_iter_init (message, &iter);
1102  if (!dbus_message_iter_get_args (&iter, &error,
1103  DBUS_TYPE_UINT32, &our_uint1,
1105  &our_string_array1, &our_string_array_len1,
1106 #ifdef HAVE_UNIX_FD_PASSING
1107  DBUS_TYPE_UNIX_FD, &our_unix_fd1,
1108 #endif
1109  DBUS_TYPE_UINT32, &our_uint2,
1110  DBUS_TYPE_UINT32, &our_uint3,
1112  {
1113  _dbus_verbose ("expected error: %s - %s\n", error.name,
1114  (error.message != NULL) ? error.message : "no message");
1115  /* ensure array of string and unix fd not leaked */
1116  _dbus_assert (our_string_array1 == NULL);
1117 #ifdef HAVE_UNIX_FD_PASSING
1118  _dbus_assert (our_unix_fd1 == -1);
1119 #endif
1120  }
1121  else
1122  {
1123  _dbus_warn ("error: parse with wrong signature: 'uashuu'.");
1124  }
1125 
1126  /* parse with wrong signature: "uashuashu" */
1127  dbus_message_iter_init (message, &iter);
1128  dbus_error_free (&error);
1129  if (!dbus_message_iter_get_args (&iter, &error,
1130  DBUS_TYPE_UINT32, &our_uint1,
1132  &our_string_array1, &our_string_array_len1,
1133 #ifdef HAVE_UNIX_FD_PASSING
1134  DBUS_TYPE_UNIX_FD, &our_unix_fd1,
1135 #endif
1136  DBUS_TYPE_UINT32, &our_uint2,
1138  &our_string_array2, &our_string_array_len2,
1139 #ifdef HAVE_UNIX_FD_PASSING
1140  DBUS_TYPE_UNIX_FD, &our_unix_fd2,
1141 #endif
1142  DBUS_TYPE_UINT32, &our_uint3,
1144  {
1145  _dbus_verbose ("expected error: %s - %s\n", error.name,
1146  (error.message != NULL) ? error.message : "no message");
1147  /* ensure array of string and unix fd not leaked */
1148  _dbus_assert (our_string_array1 == NULL);
1149  _dbus_assert (our_string_array2 == NULL);
1150 #ifdef HAVE_UNIX_FD_PASSING
1151  _dbus_assert (our_unix_fd1 == -1);
1152  _dbus_assert (our_unix_fd2 == -1);
1153 #endif
1154  }
1155  else
1156  {
1157  _dbus_warn ("error: parse with wrong signature: 'uashuashu'.");
1158  }
1159 
1160  /* parse with correct signature: "uashuash" */
1161  dbus_message_iter_init (message, &iter);
1162  dbus_error_free (&error);
1163  if (!dbus_message_iter_get_args (&iter, &error,
1164  DBUS_TYPE_UINT32, &our_uint1,
1166  &our_string_array1, &our_string_array_len1,
1167 #ifdef HAVE_UNIX_FD_PASSING
1168  DBUS_TYPE_UNIX_FD, &our_unix_fd1,
1169 #endif
1170  DBUS_TYPE_UINT32, &our_uint2,
1172  &our_string_array2, &our_string_array_len2,
1173 #ifdef HAVE_UNIX_FD_PASSING
1174  DBUS_TYPE_UNIX_FD, &our_unix_fd2,
1175 #endif
1177  {
1178  _dbus_warn ("error: %s - %s", error.name,
1179  (error.message != NULL) ? error.message : "no message");
1180  _dbus_assert_not_reached ("Could not get arguments");
1181  }
1182  else
1183  {
1184  dbus_free_string_array (our_string_array1);
1185  dbus_free_string_array (our_string_array2);
1186 #ifdef HAVE_UNIX_FD_PASSING
1187  _dbus_close (our_unix_fd1, &error);
1188  _dbus_close (our_unix_fd2, &error);
1189 #endif
1190  }
1191  _dbus_check_fdleaks_leave (initial_fds);
1192 }
1193 
1201 _dbus_message_test (const char *test_data_dir)
1202 {
1203  DBusMessage *message, *message_without_unix_fds;
1204  DBusMessageLoader *loader;
1205  int i;
1206  const char *data;
1207  DBusMessage *copy;
1208  const char *name1;
1209  const char *name2;
1210  const dbus_uint32_t our_uint32_array[] =
1211  { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
1212  const dbus_int32_t our_int32_array[] =
1213  { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
1214  const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array;
1215  const dbus_int32_t *v_ARRAY_INT32 = our_int32_array;
1216  const dbus_uint64_t our_uint64_array[] =
1217  { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
1218  const dbus_int64_t our_int64_array[] =
1219  { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
1220  const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array;
1221  const dbus_int64_t *v_ARRAY_INT64 = our_int64_array;
1222  const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
1223  const char *our_string_array1[] = { "foo", "Bar", "", "Woo woo Woo woo" };
1224  const char **v_ARRAY_STRING = our_string_array;
1225  const char **v1_ARRAY_STRING = our_string_array1;
1226  const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
1227  const double *v_ARRAY_DOUBLE = our_double_array;
1228  const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
1229  const unsigned char *v_ARRAY_BYTE = our_byte_array;
1230  const dbus_bool_t our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
1231  const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array;
1232  char sig[64];
1233  const char *s;
1234  const char *v_STRING;
1235  double v_DOUBLE;
1236  dbus_int16_t v_INT16;
1237  dbus_uint16_t v_UINT16;
1238  dbus_int32_t v_INT32;
1239  dbus_uint32_t v_UINT32;
1240  dbus_uint32_t v1_UINT32;
1241  dbus_int64_t v_INT64;
1242  dbus_uint64_t v_UINT64;
1243  unsigned char v_BYTE;
1244  unsigned char v2_BYTE;
1245  dbus_bool_t v_BOOLEAN;
1246  DBusMessageIter iter, array_iter, struct_iter;
1247 #ifdef HAVE_UNIX_FD_PASSING
1248  int v_UNIX_FD;
1249  int v1_UNIX_FD;
1250 #endif
1251  char **decomposed;
1252  DBusInitialFDs *initial_fds;
1253  dbus_bool_t ok;
1254  char basic_types[] = DBUS_TYPE_BYTE_AS_STRING \
1264 
1265  initial_fds = _dbus_check_fdleaks_enter ();
1266 
1267  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1268  "/org/freedesktop/TestPath",
1269  "Foo.TestInterface",
1270  "TestMethod");
1271  _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
1272  _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface",
1273  "TestMethod"));
1274  _dbus_assert (strcmp (dbus_message_get_path (message),
1275  "/org/freedesktop/TestPath") == 0);
1276  dbus_message_set_serial (message, 1234);
1277 
1278  /* string length including nul byte not a multiple of 4 */
1279  if (!dbus_message_set_sender (message, "org.foo.bar1"))
1280  _dbus_assert_not_reached ("out of memory");
1281 
1282  _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1"));
1283  dbus_message_set_reply_serial (message, 5678);
1284 
1286  _dbus_string_get_length (&message->header.data));
1287  _dbus_verbose_bytes_of_string (&message->body, 0,
1288  _dbus_string_get_length (&message->body));
1289 
1290  if (!dbus_message_set_sender (message, NULL))
1291  _dbus_assert_not_reached ("out of memory");
1292 
1293 
1295  _dbus_string_get_length (&message->header.data));
1296  _dbus_verbose_bytes_of_string (&message->body, 0,
1297  _dbus_string_get_length (&message->body));
1298 
1299 
1300  _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1"));
1301  _dbus_assert (dbus_message_get_serial (message) == 1234);
1302  _dbus_assert (dbus_message_get_reply_serial (message) == 5678);
1303  _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
1304 
1306  dbus_message_set_no_reply (message, TRUE);
1308  dbus_message_set_no_reply (message, FALSE);
1310 
1311  /* Set/get some header fields */
1312 
1313  if (!dbus_message_set_path (message, "/foo"))
1314  _dbus_assert_not_reached ("out of memory");
1315  _dbus_assert (strcmp (dbus_message_get_path (message),
1316  "/foo") == 0);
1317 
1318  if (!dbus_message_set_interface (message, "org.Foo"))
1319  _dbus_assert_not_reached ("out of memory");
1320  _dbus_assert (strcmp (dbus_message_get_interface (message),
1321  "org.Foo") == 0);
1322 
1323  if (!dbus_message_set_member (message, "Bar"))
1324  _dbus_assert_not_reached ("out of memory");
1325  _dbus_assert (strcmp (dbus_message_get_member (message),
1326  "Bar") == 0);
1327 
1328  /* Set/get them with longer values */
1329  if (!dbus_message_set_path (message, "/foo/bar"))
1330  _dbus_assert_not_reached ("out of memory");
1331  _dbus_assert (strcmp (dbus_message_get_path (message),
1332  "/foo/bar") == 0);
1333 
1334  if (!dbus_message_set_interface (message, "org.Foo.Bar"))
1335  _dbus_assert_not_reached ("out of memory");
1336  _dbus_assert (strcmp (dbus_message_get_interface (message),
1337  "org.Foo.Bar") == 0);
1338 
1339  if (!dbus_message_set_member (message, "BarFoo"))
1340  _dbus_assert_not_reached ("out of memory");
1341  _dbus_assert (strcmp (dbus_message_get_member (message),
1342  "BarFoo") == 0);
1343 
1344  /* Realloc shorter again */
1345 
1346  if (!dbus_message_set_path (message, "/foo"))
1347  _dbus_assert_not_reached ("out of memory");
1348  _dbus_assert (strcmp (dbus_message_get_path (message),
1349  "/foo") == 0);
1350 
1351  if (!dbus_message_set_interface (message, "org.Foo"))
1352  _dbus_assert_not_reached ("out of memory");
1353  _dbus_assert (strcmp (dbus_message_get_interface (message),
1354  "org.Foo") == 0);
1355 
1356  if (!dbus_message_set_member (message, "Bar"))
1357  _dbus_assert_not_reached ("out of memory");
1358  _dbus_assert (strcmp (dbus_message_get_member (message),
1359  "Bar") == 0);
1360 
1361  /* Path decomposing */
1362  dbus_message_set_path (message, NULL);
1363  dbus_message_get_path_decomposed (message, &decomposed);
1364  _dbus_assert (decomposed == NULL);
1365  dbus_free_string_array (decomposed);
1366 
1367  dbus_message_set_path (message, "/");
1368  dbus_message_get_path_decomposed (message, &decomposed);
1369  _dbus_assert (decomposed != NULL);
1370  _dbus_assert (decomposed[0] == NULL);
1371  dbus_free_string_array (decomposed);
1372 
1373  dbus_message_set_path (message, "/a/b");
1374  dbus_message_get_path_decomposed (message, &decomposed);
1375  _dbus_assert (decomposed != NULL);
1376  _dbus_assert (strcmp (decomposed[0], "a") == 0);
1377  _dbus_assert (strcmp (decomposed[1], "b") == 0);
1378  _dbus_assert (decomposed[2] == NULL);
1379  dbus_free_string_array (decomposed);
1380 
1381  dbus_message_set_path (message, "/spam/eggs");
1382  dbus_message_get_path_decomposed (message, &decomposed);
1383  _dbus_assert (decomposed != NULL);
1384  _dbus_assert (strcmp (decomposed[0], "spam") == 0);
1385  _dbus_assert (strcmp (decomposed[1], "eggs") == 0);
1386  _dbus_assert (decomposed[2] == NULL);
1387  dbus_free_string_array (decomposed);
1388 
1389  dbus_message_unref (message);
1390 
1391  /* Test the vararg functions */
1392  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1393  "/org/freedesktop/TestPath",
1394  "Foo.TestInterface",
1395  "TestMethod");
1396  dbus_message_set_serial (message, 1);
1397  dbus_message_set_reply_serial (message, 5678);
1398 
1399  v_INT16 = -0x123;
1400  v_UINT16 = 0x123;
1401  v_INT32 = -0x12345678;
1402  v_UINT32 = 0x12300042;
1403  v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd);
1404  v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd);
1405  v_STRING = "Test string";
1406  v_DOUBLE = 3.14159;
1407  v_BOOLEAN = TRUE;
1408  v_BYTE = 42;
1409  v2_BYTE = 24;
1410 #ifdef HAVE_UNIX_FD_PASSING
1411  v_UNIX_FD = 1;
1412  v1_UNIX_FD = 2;
1413 #endif
1414 
1415  dbus_message_append_args (message,
1416  DBUS_TYPE_INT16, &v_INT16,
1417  DBUS_TYPE_UINT16, &v_UINT16,
1418  DBUS_TYPE_INT32, &v_INT32,
1419  DBUS_TYPE_UINT32, &v_UINT32,
1420  DBUS_TYPE_INT64, &v_INT64,
1421  DBUS_TYPE_UINT64, &v_UINT64,
1422  DBUS_TYPE_STRING, &v_STRING,
1423  DBUS_TYPE_DOUBLE, &v_DOUBLE,
1424  DBUS_TYPE_BOOLEAN, &v_BOOLEAN,
1425  DBUS_TYPE_BYTE, &v_BYTE,
1426  DBUS_TYPE_BYTE, &v2_BYTE,
1427  DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32,
1428  _DBUS_N_ELEMENTS (our_uint32_array),
1429  DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32,
1430  _DBUS_N_ELEMENTS (our_int32_array),
1431  DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64,
1432  _DBUS_N_ELEMENTS (our_uint64_array),
1433  DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64,
1434  _DBUS_N_ELEMENTS (our_int64_array),
1435  DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE,
1436  _DBUS_N_ELEMENTS (our_double_array),
1437  DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE,
1438  _DBUS_N_ELEMENTS (our_byte_array),
1439  DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN,
1440  _DBUS_N_ELEMENTS (our_boolean_array),
1441  DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING,
1442  _DBUS_N_ELEMENTS (our_string_array),
1443 
1445 
1446  i = 0;
1447  sig[i++] = DBUS_TYPE_INT16;
1448  sig[i++] = DBUS_TYPE_UINT16;
1449  sig[i++] = DBUS_TYPE_INT32;
1450  sig[i++] = DBUS_TYPE_UINT32;
1451  sig[i++] = DBUS_TYPE_INT64;
1452  sig[i++] = DBUS_TYPE_UINT64;
1453  sig[i++] = DBUS_TYPE_STRING;
1454  sig[i++] = DBUS_TYPE_DOUBLE;
1455  sig[i++] = DBUS_TYPE_BOOLEAN;
1456  sig[i++] = DBUS_TYPE_BYTE;
1457  sig[i++] = DBUS_TYPE_BYTE;
1458  sig[i++] = DBUS_TYPE_ARRAY;
1459  sig[i++] = DBUS_TYPE_UINT32;
1460  sig[i++] = DBUS_TYPE_ARRAY;
1461  sig[i++] = DBUS_TYPE_INT32;
1462  sig[i++] = DBUS_TYPE_ARRAY;
1463  sig[i++] = DBUS_TYPE_UINT64;
1464  sig[i++] = DBUS_TYPE_ARRAY;
1465  sig[i++] = DBUS_TYPE_INT64;
1466  sig[i++] = DBUS_TYPE_ARRAY;
1467  sig[i++] = DBUS_TYPE_DOUBLE;
1468  sig[i++] = DBUS_TYPE_ARRAY;
1469  sig[i++] = DBUS_TYPE_BYTE;
1470  sig[i++] = DBUS_TYPE_ARRAY;
1471  sig[i++] = DBUS_TYPE_BOOLEAN;
1472  sig[i++] = DBUS_TYPE_ARRAY;
1473  sig[i++] = DBUS_TYPE_STRING;
1474 
1475  message_without_unix_fds = dbus_message_copy(message);
1476  _dbus_assert(message_without_unix_fds);
1477 #ifdef HAVE_UNIX_FD_PASSING
1478  dbus_message_append_args (message,
1479  DBUS_TYPE_UNIX_FD, &v_UNIX_FD,
1481  sig[i++] = DBUS_TYPE_UNIX_FD;
1482 #endif
1483  sig[i++] = DBUS_TYPE_INVALID;
1484 
1485  _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
1486 
1487  _dbus_verbose ("HEADER\n");
1489  _dbus_string_get_length (&message->header.data));
1490  _dbus_verbose ("BODY\n");
1491  _dbus_verbose_bytes_of_string (&message->body, 0,
1492  _dbus_string_get_length (&message->body));
1493 
1494  _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n",
1495  sig, dbus_message_get_signature (message));
1496 
1497  s = dbus_message_get_signature (message);
1498 
1499  _dbus_assert (dbus_message_has_signature (message, sig));
1500  _dbus_assert (strcmp (s, sig) == 0);
1501 
1502  verify_test_message (message);
1503 
1504  copy = dbus_message_copy (message);
1505 
1508  _dbus_assert (message->header.padding == copy->header.padding);
1509 
1512 
1513  _dbus_assert (_dbus_string_get_length (&message->body) ==
1514  _dbus_string_get_length (&copy->body));
1515 
1516  verify_test_message (copy);
1517 
1518  name1 = dbus_message_get_interface (message);
1519  name2 = dbus_message_get_interface (copy);
1520 
1521  _dbus_assert (strcmp (name1, name2) == 0);
1522 
1523  name1 = dbus_message_get_member (message);
1524  name2 = dbus_message_get_member (copy);
1525 
1526  _dbus_assert (strcmp (name1, name2) == 0);
1527 
1528  dbus_message_unref (copy);
1529 
1530  /* Message loader test */
1531  dbus_message_lock (message);
1532  loader = _dbus_message_loader_new ();
1533 
1534  /* check ref/unref */
1535  _dbus_message_loader_ref (loader);
1536  _dbus_message_loader_unref (loader);
1537 
1538  /* Write the header data one byte at a time */
1539  data = _dbus_string_get_const_data (&message->header.data);
1540  for (i = 0; i < _dbus_string_get_length (&message->header.data); i++)
1541  {
1542  DBusString *buffer;
1543 
1544  _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
1545  _dbus_string_append_byte (buffer, data[i]);
1546  _dbus_message_loader_return_buffer (loader, buffer);
1547  }
1548 
1549  /* Write the body data one byte at a time */
1550  data = _dbus_string_get_const_data (&message->body);
1551  for (i = 0; i < _dbus_string_get_length (&message->body); i++)
1552  {
1553  DBusString *buffer;
1554 
1555  _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
1556  _dbus_string_append_byte (buffer, data[i]);
1557  _dbus_message_loader_return_buffer (loader, buffer);
1558  }
1559 
1560 #ifdef HAVE_UNIX_FD_PASSING
1561  {
1562  int *unix_fds;
1563  unsigned n_unix_fds;
1564  /* Write unix fd */
1565  _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds);
1566  _dbus_assert(n_unix_fds > 0);
1567  _dbus_assert(message->n_unix_fds == 1);
1568  unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL);
1569  _dbus_assert(unix_fds[0] >= 0);
1570  _dbus_message_loader_return_unix_fds(loader, unix_fds, 1);
1571  }
1572 #endif
1573 
1574  dbus_message_unref (message);
1575 
1576  /* Now pop back the message */
1578  _dbus_assert_not_reached ("no memory to queue messages");
1579 
1581  _dbus_assert_not_reached ("message loader corrupted");
1582 
1583  message = _dbus_message_loader_pop_message (loader);
1584  if (!message)
1585  _dbus_assert_not_reached ("received a NULL message");
1586 
1587  if (dbus_message_get_reply_serial (message) != 5678)
1588  _dbus_assert_not_reached ("reply serial fields differ");
1589 
1590  dbus_message_unref (message);
1591 
1592  /* ovveride the serial, since it was reset by dbus_message_copy() */
1593  dbus_message_set_serial(message_without_unix_fds, 8901);
1594 
1595  dbus_message_lock (message_without_unix_fds);
1596 
1597  verify_test_message (message_without_unix_fds);
1598 
1599  {
1600  /* Marshal and demarshal the message. */
1601 
1602  DBusMessage *message2;
1603  DBusError error = DBUS_ERROR_INIT;
1604  char *marshalled = NULL;
1605  int len = 0;
1606  char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx";
1607 
1608  if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len))
1609  _dbus_assert_not_reached ("failed to marshal message");
1610 
1611  _dbus_assert (len != 0);
1612  _dbus_assert (marshalled != NULL);
1613 
1614  _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len);
1615  message2 = dbus_message_demarshal (marshalled, len, &error);
1616 
1617  _dbus_assert (message2 != NULL);
1618  _dbus_assert (!dbus_error_is_set (&error));
1619  verify_test_message (message2);
1620 
1621  dbus_message_unref (message2);
1622  dbus_free (marshalled);
1623 
1624  /* Demarshal invalid message. */
1625 
1626  message2 = dbus_message_demarshal ("invalid", 7, &error);
1627  _dbus_assert (message2 == NULL);
1628  _dbus_assert (dbus_error_is_set (&error));
1629  dbus_error_free (&error);
1630 
1631  /* Demarshal invalid (empty) message. */
1632 
1633  message2 = dbus_message_demarshal ("", 0, &error);
1634  _dbus_assert (message2 == NULL);
1635  _dbus_assert (dbus_error_is_set (&error));
1636  dbus_error_free (&error);
1637 
1638  /* Bytes needed to demarshal empty message: 0 (more) */
1639 
1641 
1642  /* Bytes needed to demarshal invalid message: -1 (error). */
1643 
1645  }
1646 
1647  dbus_message_unref (message_without_unix_fds);
1648  _dbus_message_loader_unref (loader);
1649 
1650  check_memleaks ();
1651  _dbus_check_fdleaks_leave (initial_fds);
1652  initial_fds = _dbus_check_fdleaks_enter ();
1653 
1654  /* Test enumeration of array elements */
1655  for (i = strlen (basic_types) - 1; i > 0; i--)
1656  {
1657  DBusBasicValue val;
1658  int some;
1659  char* signature = _dbus_strdup ("?");
1660 
1661  signature[0] = basic_types[i];
1662  s = "SomeThingToSay";
1663  memset (&val, '\0', sizeof (val));
1664 
1665  message = dbus_message_new_method_call ("de.ende.test",
1666  "/de/ende/test", "de.ende.Test", "ArtistName");
1667  _dbus_assert (message != NULL);
1668  dbus_message_iter_init_append (message, &iter);
1670  signature, &array_iter);
1671  for (some = 0; some < 3; some++)
1672  {
1673  if (basic_types[i] == DBUS_TYPE_STRING)
1675  else
1676  dbus_message_iter_append_basic (&array_iter, basic_types[i], &val);
1677  }
1678  dbus_message_iter_close_container (&iter, &array_iter);
1679  dbus_message_iter_init (message, &iter);
1681  dbus_message_unref (message);
1682  dbus_free (signature);
1683  }
1684  /* Array of structs */
1685  message = dbus_message_new_method_call ("de.ende.test",
1686  "/de/ende/test", "de.ende.Test", "ArtistName");
1687  _dbus_assert (message != NULL);
1688  dbus_message_iter_init_append (message, &iter);
1692  DBUS_STRUCT_END_CHAR_AS_STRING, &array_iter);
1694  NULL, &struct_iter);
1695  s = "SpamAndEggs";
1697  dbus_message_iter_close_container (&array_iter, &struct_iter);
1698  dbus_message_iter_close_container (&iter, &array_iter);
1699  dbus_message_iter_init (message, &iter);
1701  dbus_message_unref (message);
1702  check_memleaks ();
1703 
1704  /* Check that we can abandon a container */
1705  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1706  "/org/freedesktop/TestPath",
1707  "Foo.TestInterface",
1708  "Method");
1709 
1710  dbus_message_iter_init_append (message, &iter);
1711 
1717  &array_iter);
1718  _dbus_assert (ok);
1720  NULL, &struct_iter);
1721  _dbus_assert (ok);
1722  s = "peaches";
1723  ok = dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING, &s);
1724  _dbus_assert (ok);
1725 
1726  /* uh-oh, error, try and unwind */
1727 
1728  dbus_message_iter_abandon_container (&array_iter, &struct_iter);
1729  dbus_message_iter_abandon_container (&array_iter, &iter);
1730 
1731  dbus_message_unref (message);
1732 
1733  /* Check we should not leak array of string or unix fd, fd.o#21259 */
1734  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1735  "/org/freedesktop/TestPath",
1736  "Foo.TestInterface",
1737  "Method");
1738 
1739  /* signature "uashuash" */
1740  dbus_message_append_args (message,
1741  DBUS_TYPE_UINT32, &v_UINT32,
1742  DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING,
1743  _DBUS_N_ELEMENTS (our_string_array),
1744 #ifdef HAVE_UNIX_FD_PASSING
1745  DBUS_TYPE_UNIX_FD, &v_UNIX_FD,
1746 #endif
1747  DBUS_TYPE_UINT32, &v1_UINT32,
1748  DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v1_ARRAY_STRING,
1749  _DBUS_N_ELEMENTS (our_string_array1),
1750 #ifdef HAVE_UNIX_FD_PASSING
1751  DBUS_TYPE_UNIX_FD, &v1_UNIX_FD,
1752 #endif
1753 
1755 
1756  i = 0;
1757  sig[i++] = DBUS_TYPE_UINT32;
1758  sig[i++] = DBUS_TYPE_ARRAY;
1759  sig[i++] = DBUS_TYPE_STRING;
1760 #ifdef HAVE_UNIX_FD_PASSING
1761  sig[i++] = DBUS_TYPE_UNIX_FD;
1762 #endif
1763  sig[i++] = DBUS_TYPE_UINT32;
1764  sig[i++] = DBUS_TYPE_ARRAY;
1765  sig[i++] = DBUS_TYPE_STRING;
1766 #ifdef HAVE_UNIX_FD_PASSING
1767  sig[i++] = DBUS_TYPE_UNIX_FD;
1768 #endif
1769  sig[i++] = DBUS_TYPE_INVALID;
1770 
1771  _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
1772 
1773  verify_test_message_args_ignored (message);
1774  verify_test_message_memleak (message);
1775 
1776  dbus_message_unref (message);
1777 
1778  /* Load all the sample messages from the message factory */
1779  {
1780  DBusMessageDataIter diter;
1781  DBusMessageData mdata;
1782  int count;
1783 
1784  reset_validities_seen ();
1785 
1786  count = 0;
1787  _dbus_message_data_iter_init (&diter);
1788 
1789  while (_dbus_message_data_iter_get_and_next (&diter,
1790  &mdata))
1791  {
1792  if (!dbus_internal_do_not_use_try_message_data (&mdata.data,
1793  mdata.expected_validity))
1794  {
1795  _dbus_warn ("expected validity %d and did not get it",
1796  mdata.expected_validity);
1797  _dbus_assert_not_reached ("message data failed");
1798  }
1799 
1800  _dbus_message_data_free (&mdata);
1801 
1802  count += 1;
1803  }
1804 
1805  printf ("%d sample messages tested\n", count);
1806 
1807  print_validities_seen (FALSE);
1808  print_validities_seen (TRUE);
1809  }
1810 
1811  check_memleaks ();
1812  _dbus_check_fdleaks_leave (initial_fds);
1813 
1814  /* Now load every message in test_data_dir if we have one */
1815  if (test_data_dir == NULL)
1816  return TRUE;
1817 
1818  initial_fds = _dbus_check_fdleaks_enter ();
1819 
1820  if (!dbus_internal_do_not_use_foreach_message_file (test_data_dir,
1821  (DBusForeachMessageFileFunc)
1822  dbus_internal_do_not_use_try_message_file,
1823  NULL))
1824  _dbus_assert_not_reached ("foreach_message_file test failed");
1825 
1826  _dbus_check_fdleaks_leave (initial_fds);
1827 
1828  return TRUE;
1829 }
1830 
1831 #endif /* DBUS_ENABLE_EMBEDDED_TESTS */