D-Bus  1.6.12
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 
48 #ifdef DBUS_BUILD_TESTS
49 
61 static dbus_bool_t
62 dbus_message_iter_get_args (DBusMessageIter *iter,
63  DBusError *error,
64  int first_arg_type,
65  ...)
66 {
67  dbus_bool_t retval;
68  va_list var_args;
69 
70  _dbus_return_val_if_fail (iter != NULL, FALSE);
71  _dbus_return_val_if_error_is_set (error, FALSE);
72 
73  va_start (var_args, first_arg_type);
74  retval = _dbus_message_iter_get_args_valist (iter, error, first_arg_type, var_args);
75  va_end (var_args);
76 
77  return retval;
78 }
79 #endif /* DBUS_BUILD_TESTS */
80 
83 #ifdef DBUS_BUILD_TESTS
84 #include "dbus-test.h"
85 #include "dbus-message-factory.h"
86 #include <stdio.h>
87 #include <stdlib.h>
88 
89 static int validities_seen[DBUS_VALIDITY_LAST + _DBUS_NEGATIVE_VALIDITY_COUNT];
90 
91 static void
92 reset_validities_seen (void)
93 {
94  int i;
95  i = 0;
96  while (i < _DBUS_N_ELEMENTS (validities_seen))
97  {
98  validities_seen[i] = 0;
99  ++i;
100  }
101 }
102 
103 static void
104 record_validity_seen (DBusValidity validity)
105 {
106  validities_seen[validity + _DBUS_NEGATIVE_VALIDITY_COUNT] += 1;
107 }
108 
109 static void
110 print_validities_seen (dbus_bool_t not_seen)
111 {
112  int i;
113  i = 0;
114  while (i < _DBUS_N_ELEMENTS (validities_seen))
115  {
116  if ((i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_VALIDITY_UNKNOWN ||
117  (i - _DBUS_NEGATIVE_VALIDITY_COUNT) == DBUS_INVALID_FOR_UNKNOWN_REASON)
118  ;
119  else if ((not_seen && validities_seen[i] == 0) ||
120  (!not_seen && validities_seen[i] > 0))
121  printf ("validity %3d seen %d times\n",
122  i - _DBUS_NEGATIVE_VALIDITY_COUNT,
123  validities_seen[i]);
124  ++i;
125  }
126 }
127 
128 static void
129 check_memleaks (void)
130 {
131  dbus_shutdown ();
132 
133  if (_dbus_get_malloc_blocks_outstanding () != 0)
134  {
135  _dbus_warn ("%d dbus_malloc blocks were not freed in %s\n",
136  _dbus_get_malloc_blocks_outstanding (), __FILE__);
137  _dbus_assert_not_reached ("memleaks");
138  }
139 }
140 
141 #ifdef __linux__
142 struct DBusInitialFDs {
143  fd_set set;
144 };
145 #endif
146 
147 DBusInitialFDs *
148 _dbus_check_fdleaks_enter (void)
149 {
150 #ifdef __linux__
151  DIR *d;
152  DBusInitialFDs *fds;
153 
154  /* this is plain malloc so it won't interfere with leak checking */
155  fds = malloc (sizeof (DBusInitialFDs));
156  _dbus_assert (fds != NULL);
157 
158  /* This works on Linux only */
159 
160  if ((d = opendir ("/proc/self/fd")))
161  {
162  struct dirent *de;
163 
164  while ((de = readdir(d)))
165  {
166  long l;
167  char *e = NULL;
168  int fd;
169 
170  if (de->d_name[0] == '.')
171  continue;
172 
173  errno = 0;
174  l = strtol (de->d_name, &e, 10);
175  _dbus_assert (errno == 0 && e && !*e);
176 
177  fd = (int) l;
178 
179  if (fd < 3)
180  continue;
181 
182  if (fd == dirfd (d))
183  continue;
184 
185  FD_SET (fd, &fds->set);
186  }
187 
188  closedir (d);
189  }
190 
191  return fds;
192 #else
193  return NULL;
194 #endif
195 }
196 
197 void
198 _dbus_check_fdleaks_leave (DBusInitialFDs *fds)
199 {
200 #ifdef __linux__
201  DIR *d;
202 
203  /* This works on Linux only */
204 
205  if ((d = opendir ("/proc/self/fd")))
206  {
207  struct dirent *de;
208 
209  while ((de = readdir(d)))
210  {
211  long l;
212  char *e = NULL;
213  int fd;
214 
215  if (de->d_name[0] == '.')
216  continue;
217 
218  errno = 0;
219  l = strtol (de->d_name, &e, 10);
220  _dbus_assert (errno == 0 && e && !*e);
221 
222  fd = (int) l;
223 
224  if (fd < 3)
225  continue;
226 
227  if (fd == dirfd (d))
228  continue;
229 
230  if (FD_ISSET (fd, &fds->set))
231  continue;
232 
233  _dbus_warn ("file descriptor %i leaked in %s.\n", fd, __FILE__);
234  _dbus_assert_not_reached ("fdleaks");
235  }
236 
237  closedir (d);
238  }
239 
240  free (fds);
241 #else
242  _dbus_assert (fds == NULL);
243 #endif
244 }
245 
246 static dbus_bool_t
247 check_have_valid_message (DBusMessageLoader *loader)
248 {
249  DBusMessage *message;
250  dbus_bool_t retval;
251 
252  message = NULL;
253  retval = FALSE;
254 
256  {
257  _dbus_warn ("loader corrupted on message that was expected to be valid; invalid reason %d\n",
258  loader->corruption_reason);
259  goto failed;
260  }
261 
262  message = _dbus_message_loader_pop_message (loader);
263  if (message == NULL)
264  {
265  _dbus_warn ("didn't load message that was expected to be valid (message not popped)\n");
266  goto failed;
267  }
268 
269  if (_dbus_string_get_length (&loader->data) > 0)
270  {
271  _dbus_warn ("had leftover bytes from expected-to-be-valid single message\n");
272  goto failed;
273  }
274 
275 #if 0
276  /* FIXME */
277  /* Verify that we're able to properly deal with the message.
278  * For example, this would detect improper handling of messages
279  * in nonstandard byte order.
280  */
281  if (!check_message_handling (message))
282  goto failed;
283 #endif
284 
285  record_validity_seen (DBUS_VALID);
286 
287  retval = TRUE;
288 
289  failed:
290  if (message)
291  dbus_message_unref (message);
292 
293  return retval;
294 }
295 
296 static dbus_bool_t
297 check_invalid_message (DBusMessageLoader *loader,
298  DBusValidity expected_validity)
299 {
300  dbus_bool_t retval;
301 
302  retval = FALSE;
303 
305  {
306  _dbus_warn ("loader not corrupted on message that was expected to be invalid\n");
307  goto failed;
308  }
309 
310  record_validity_seen (loader->corruption_reason);
311 
312  if (expected_validity != DBUS_INVALID_FOR_UNKNOWN_REASON &&
313  loader->corruption_reason != expected_validity)
314  {
315  _dbus_warn ("expected message to be corrupted for reason %d and was corrupted for %d instead\n",
316  expected_validity, loader->corruption_reason);
317  goto failed;
318  }
319 
320  retval = TRUE;
321 
322  failed:
323  return retval;
324 }
325 
326 static dbus_bool_t
327 check_incomplete_message (DBusMessageLoader *loader)
328 {
329  DBusMessage *message;
330  dbus_bool_t retval;
331 
332  message = NULL;
333  retval = FALSE;
334 
336  {
337  _dbus_warn ("loader corrupted on message that was expected to be valid (but incomplete), corruption reason %d\n",
338  loader->corruption_reason);
339  goto failed;
340  }
341 
342  message = _dbus_message_loader_pop_message (loader);
343  if (message != NULL)
344  {
345  _dbus_warn ("loaded message that was expected to be incomplete\n");
346  goto failed;
347  }
348 
349  record_validity_seen (DBUS_VALID_BUT_INCOMPLETE);
350  retval = TRUE;
351 
352  failed:
353  if (message)
354  dbus_message_unref (message);
355  return retval;
356 }
357 
358 static dbus_bool_t
359 check_loader_results (DBusMessageLoader *loader,
360  DBusValidity expected_validity)
361 {
363  _dbus_assert_not_reached ("no memory to queue messages");
364 
365  if (expected_validity == DBUS_VALID)
366  return check_have_valid_message (loader);
367  else if (expected_validity == DBUS_VALID_BUT_INCOMPLETE)
368  return check_incomplete_message (loader);
369  else if (expected_validity == DBUS_VALIDITY_UNKNOWN)
370  {
371  /* here we just know we didn't segfault and that was the
372  * only test. Also, we record that we got coverage
373  * for the validity reason.
374  */
376  record_validity_seen (loader->corruption_reason);
377 
378  return TRUE;
379  }
380  else
381  return check_invalid_message (loader, expected_validity);
382 }
383 
392 dbus_internal_do_not_use_load_message_file (const DBusString *filename,
393  DBusString *data)
394 {
395  dbus_bool_t retval;
396  DBusError error = DBUS_ERROR_INIT;
397 
398  retval = FALSE;
399 
400  _dbus_verbose ("Loading raw %s\n", _dbus_string_get_const_data (filename));
401  if (!_dbus_file_get_contents (data, filename, &error))
402  {
403  _dbus_warn ("Could not load message file %s: %s\n",
404  _dbus_string_get_const_data (filename),
405  error.message);
406  dbus_error_free (&error);
407  goto failed;
408  }
409 
410  retval = TRUE;
411 
412  failed:
413 
414  return retval;
415 }
416 
426 dbus_internal_do_not_use_try_message_file (const DBusString *filename,
427  DBusValidity expected_validity)
428 {
429  DBusString data;
430  dbus_bool_t retval;
431 
432  retval = FALSE;
433 
434  if (!_dbus_string_init (&data))
435  _dbus_assert_not_reached ("could not allocate string\n");
436 
437  if (!dbus_internal_do_not_use_load_message_file (filename, &data))
438  goto failed;
439 
440  retval = dbus_internal_do_not_use_try_message_data (&data, expected_validity);
441 
442  failed:
443 
444  if (!retval)
445  {
446  if (_dbus_string_get_length (&data) > 0)
448  _dbus_string_get_length (&data));
449 
450  _dbus_warn ("Failed message loader test on %s\n",
451  _dbus_string_get_const_data (filename));
452  }
453 
454  _dbus_string_free (&data);
455 
456  return retval;
457 }
458 
468 dbus_internal_do_not_use_try_message_data (const DBusString *data,
469  DBusValidity expected_validity)
470 {
471  DBusMessageLoader *loader;
472  dbus_bool_t retval;
473  int len;
474  int i;
475 
476  loader = NULL;
477  retval = FALSE;
478 
479  /* Write the data one byte at a time */
480 
481  loader = _dbus_message_loader_new ();
482 
483  /* check some trivial loader functions */
484  _dbus_message_loader_ref (loader);
487 
488  len = _dbus_string_get_length (data);
489  for (i = 0; i < len; i++)
490  {
491  DBusString *buffer;
492 
493  _dbus_message_loader_get_buffer (loader, &buffer);
494  _dbus_string_append_byte (buffer,
495  _dbus_string_get_byte (data, i));
496  _dbus_message_loader_return_buffer (loader, buffer, 1);
497  }
498 
499  if (!check_loader_results (loader, expected_validity))
500  goto failed;
501 
503  loader = NULL;
504 
505  /* Write the data all at once */
506 
507  loader = _dbus_message_loader_new ();
508 
509  {
510  DBusString *buffer;
511 
512  _dbus_message_loader_get_buffer (loader, &buffer);
513  _dbus_string_copy (data, 0, buffer,
514  _dbus_string_get_length (buffer));
515  _dbus_message_loader_return_buffer (loader, buffer, 1);
516  }
517 
518  if (!check_loader_results (loader, expected_validity))
519  goto failed;
520 
522  loader = NULL;
523 
524  /* Write the data 2 bytes at a time */
525 
526  loader = _dbus_message_loader_new ();
527 
528  len = _dbus_string_get_length (data);
529  for (i = 0; i < len; i += 2)
530  {
531  DBusString *buffer;
532 
533  _dbus_message_loader_get_buffer (loader, &buffer);
534  _dbus_string_append_byte (buffer,
535  _dbus_string_get_byte (data, i));
536  if ((i+1) < len)
537  _dbus_string_append_byte (buffer,
538  _dbus_string_get_byte (data, i+1));
539  _dbus_message_loader_return_buffer (loader, buffer, 1);
540  }
541 
542  if (!check_loader_results (loader, expected_validity))
543  goto failed;
544 
546  loader = NULL;
547 
548  retval = TRUE;
549 
550  failed:
551 
552  if (loader)
554 
555  return retval;
556 }
557 
558 static dbus_bool_t
559 process_test_subdir (const DBusString *test_base_dir,
560  const char *subdir,
561  DBusValidity expected_validity,
562  DBusForeachMessageFileFunc function,
563  void *user_data)
564 {
565  DBusString test_directory;
566  DBusString filename;
567  DBusDirIter *dir;
568  dbus_bool_t retval;
569  DBusError error = DBUS_ERROR_INIT;
570 
571  retval = FALSE;
572  dir = NULL;
573 
574  if (!_dbus_string_init (&test_directory))
575  _dbus_assert_not_reached ("didn't allocate test_directory\n");
576 
577  _dbus_string_init_const (&filename, subdir);
578 
579  if (!_dbus_string_copy (test_base_dir, 0,
580  &test_directory, 0))
581  _dbus_assert_not_reached ("couldn't copy test_base_dir to test_directory");
582 
583  if (!_dbus_concat_dir_and_file (&test_directory, &filename))
584  _dbus_assert_not_reached ("couldn't allocate full path");
585 
586  _dbus_string_free (&filename);
587  if (!_dbus_string_init (&filename))
588  _dbus_assert_not_reached ("didn't allocate filename string\n");
589 
590  dir = _dbus_directory_open (&test_directory, &error);
591  if (dir == NULL)
592  {
593  _dbus_warn ("Could not open %s: %s\n",
594  _dbus_string_get_const_data (&test_directory),
595  error.message);
596  dbus_error_free (&error);
597  goto failed;
598  }
599 
600  printf ("Testing %s:\n", subdir);
601 
602  next:
603  while (_dbus_directory_get_next_file (dir, &filename, &error))
604  {
605  DBusString full_path;
606 
607  if (!_dbus_string_init (&full_path))
608  _dbus_assert_not_reached ("couldn't init string");
609 
610  if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
611  _dbus_assert_not_reached ("couldn't copy dir to full_path");
612 
613  if (!_dbus_concat_dir_and_file (&full_path, &filename))
614  _dbus_assert_not_reached ("couldn't concat file to dir");
615 
616  if (_dbus_string_ends_with_c_str (&filename, ".message-raw"))
617  ;
618  else
619  {
620  if (_dbus_string_ends_with_c_str (&filename, ".message"))
621  {
622  printf ("SKIP: Could not load %s, message builder language no longer supported\n",
623  _dbus_string_get_const_data (&filename));
624  }
625 
626  _dbus_verbose ("Skipping non-.message file %s\n",
627  _dbus_string_get_const_data (&filename));
628  _dbus_string_free (&full_path);
629  goto next;
630  }
631 
632  printf (" %s\n",
633  _dbus_string_get_const_data (&filename));
634 
635  if (! (*function) (&full_path,
636  expected_validity, user_data))
637  {
638  _dbus_string_free (&full_path);
639  goto failed;
640  }
641  else
642  _dbus_string_free (&full_path);
643  }
644 
645  if (dbus_error_is_set (&error))
646  {
647  _dbus_warn ("Could not get next file in %s: %s\n",
648  _dbus_string_get_const_data (&test_directory),
649  error.message);
650  dbus_error_free (&error);
651  goto failed;
652  }
653 
654  retval = TRUE;
655 
656  failed:
657 
658  if (dir)
659  _dbus_directory_close (dir);
660  _dbus_string_free (&test_directory);
661  _dbus_string_free (&filename);
662 
663  return retval;
664 }
665 
676 dbus_internal_do_not_use_foreach_message_file (const char *test_data_dir,
677  DBusForeachMessageFileFunc func,
678  void *user_data)
679 {
680  DBusString test_directory;
681  dbus_bool_t retval;
682 
683  retval = FALSE;
684 
685  _dbus_string_init_const (&test_directory, test_data_dir);
686 
687  if (!process_test_subdir (&test_directory, "valid-messages",
688  DBUS_VALID, func, user_data))
689  goto failed;
690 
691  check_memleaks ();
692 
693  if (!process_test_subdir (&test_directory, "invalid-messages",
694  DBUS_INVALID_FOR_UNKNOWN_REASON, func, user_data))
695  goto failed;
696 
697  check_memleaks ();
698 
699  if (!process_test_subdir (&test_directory, "incomplete-messages",
700  DBUS_VALID_BUT_INCOMPLETE, func, user_data))
701  goto failed;
702 
703  check_memleaks ();
704 
705  retval = TRUE;
706 
707  failed:
708 
709  _dbus_string_free (&test_directory);
710 
711  return retval;
712 }
713 
714 #if 0
715 #define GET_AND_CHECK(iter, typename, literal) \
716  do { \
717  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \
718  _dbus_assert_not_reached ("got wrong argument type from message iter"); \
719  dbus_message_iter_get_basic (&iter, &v_##typename); \
720  if (v_##typename != literal) \
721  _dbus_assert_not_reached ("got wrong value from message iter"); \
722  } while (0)
723 
724 #define GET_AND_CHECK_STRCMP(iter, typename, literal) \
725  do { \
726  if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_##typename) \
727  _dbus_assert_not_reached ("got wrong argument type from message iter"); \
728  dbus_message_iter_get_basic (&iter, &v_##typename); \
729  if (strcmp (v_##typename, literal) != 0) \
730  _dbus_assert_not_reached ("got wrong value from message iter"); \
731  } while (0)
732 
733 #define GET_AND_CHECK_AND_NEXT(iter, typename, literal) \
734  do { \
735  GET_AND_CHECK(iter, typename, literal); \
736  if (!dbus_message_iter_next (&iter)) \
737  _dbus_assert_not_reached ("failed to move iter to next"); \
738  } while (0)
739 
740 #define GET_AND_CHECK_STRCMP_AND_NEXT(iter, typename, literal) \
741  do { \
742  GET_AND_CHECK_STRCMP(iter, typename, literal); \
743  if (!dbus_message_iter_next (&iter)) \
744  _dbus_assert_not_reached ("failed to move iter to next"); \
745  } while (0)
746 
747 static void
748 message_iter_test (DBusMessage *message)
749 {
750  DBusMessageIter iter, array, array2;
751  const char *v_STRING;
752  double v_DOUBLE;
753  dbus_int16_t v_INT16;
754  dbus_uint16_t v_UINT16;
755  dbus_int32_t v_INT32;
756  dbus_uint32_t v_UINT32;
757 #ifdef DBUS_HAVE_INT64
758  dbus_int64_t v_INT64;
759  dbus_uint64_t v_UINT64;
760 #endif
761  unsigned char v_BYTE;
762  dbus_bool_t v_BOOLEAN;
763 
764  const dbus_int32_t *our_int_array;
765  int len;
766 
767  dbus_message_iter_init (message, &iter);
768 
769  GET_AND_CHECK_STRCMP_AND_NEXT (iter, STRING, "Test string");
770  GET_AND_CHECK_AND_NEXT (iter, INT32, -0x12345678);
771  GET_AND_CHECK_AND_NEXT (iter, UINT32, 0xedd1e);
772  GET_AND_CHECK_AND_NEXT (iter, DOUBLE, 3.14159);
773 
775  _dbus_assert_not_reached ("Argument type not an array");
776 
778  _dbus_assert_not_reached ("Array type not double");
779 
780  dbus_message_iter_recurse (&iter, &array);
781 
782  GET_AND_CHECK_AND_NEXT (array, DOUBLE, 1.5);
783  GET_AND_CHECK (array, DOUBLE, 2.5);
784 
785  if (dbus_message_iter_next (&array))
786  _dbus_assert_not_reached ("Didn't reach end of array");
787 
788  if (!dbus_message_iter_next (&iter))
789  _dbus_assert_not_reached ("Reached end of arguments");
790 
791  GET_AND_CHECK_AND_NEXT (iter, BYTE, 0xF0);
792 
794  _dbus_assert_not_reached ("no array");
795 
797  _dbus_assert_not_reached ("Array type not int32");
798 
799  /* Empty array */
800  dbus_message_iter_recurse (&iter, &array);
801 
802  if (dbus_message_iter_next (&array))
803  _dbus_assert_not_reached ("Didn't reach end of array");
804 
805  if (!dbus_message_iter_next (&iter))
806  _dbus_assert_not_reached ("Reached end of arguments");
807 
808  GET_AND_CHECK (iter, BYTE, 0xF0);
809 
810  if (dbus_message_iter_next (&iter))
811  _dbus_assert_not_reached ("Didn't reach end of arguments");
812 }
813 #endif
814 
815 static void
816 verify_test_message (DBusMessage *message)
817 {
818  DBusMessageIter iter;
819  DBusError error = DBUS_ERROR_INIT;
820  dbus_int16_t our_int16;
821  dbus_uint16_t our_uint16;
822  dbus_int32_t our_int;
823  dbus_uint32_t our_uint;
824  const char *our_str;
825  double our_double;
826  double v_DOUBLE;
827  dbus_bool_t our_bool;
828  unsigned char our_byte_1, our_byte_2;
829  const dbus_uint32_t *our_uint32_array = (void*)0xdeadbeef;
830  int our_uint32_array_len;
831  dbus_int32_t *our_int32_array = (void*)0xdeadbeef;
832  int our_int32_array_len;
833 #ifdef DBUS_HAVE_INT64
834  dbus_int64_t our_int64;
835  dbus_uint64_t our_uint64;
836  dbus_int64_t *our_uint64_array = (void*)0xdeadbeef;
837  int our_uint64_array_len;
838  const dbus_int64_t *our_int64_array = (void*)0xdeadbeef;
839  int our_int64_array_len;
840 #endif
841  const double *our_double_array = (void*)0xdeadbeef;
842  int our_double_array_len;
843  const unsigned char *our_byte_array = (void*)0xdeadbeef;
844  int our_byte_array_len;
845  const dbus_bool_t *our_boolean_array = (void*)0xdeadbeef;
846  int our_boolean_array_len;
847  char **our_string_array;
848  int our_string_array_len;
849 
850  dbus_message_iter_init (message, &iter);
851 
852  if (!dbus_message_iter_get_args (&iter, &error,
853  DBUS_TYPE_INT16, &our_int16,
854  DBUS_TYPE_UINT16, &our_uint16,
855  DBUS_TYPE_INT32, &our_int,
856  DBUS_TYPE_UINT32, &our_uint,
857 #ifdef DBUS_HAVE_INT64
858  DBUS_TYPE_INT64, &our_int64,
859  DBUS_TYPE_UINT64, &our_uint64,
860 #endif
861  DBUS_TYPE_STRING, &our_str,
862  DBUS_TYPE_DOUBLE, &our_double,
863  DBUS_TYPE_BOOLEAN, &our_bool,
864  DBUS_TYPE_BYTE, &our_byte_1,
865  DBUS_TYPE_BYTE, &our_byte_2,
867  &our_uint32_array, &our_uint32_array_len,
869  &our_int32_array, &our_int32_array_len,
870 #ifdef DBUS_HAVE_INT64
872  &our_uint64_array, &our_uint64_array_len,
873  DBUS_TYPE_ARRAY, DBUS_TYPE_INT64,
874  &our_int64_array, &our_int64_array_len,
875 #endif
876  DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE,
877  &our_double_array, &our_double_array_len,
878  DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE,
879  &our_byte_array, &our_byte_array_len,
880  DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN,
881  &our_boolean_array, &our_boolean_array_len,
882  DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,
883  &our_string_array, &our_string_array_len,
884  0))
885  {
886  _dbus_warn ("error: %s - %s\n", error.name,
887  (error.message != NULL) ? error.message : "no message");
888  _dbus_assert_not_reached ("Could not get arguments");
889  }
890 
891  if (our_int16 != -0x123)
892  _dbus_assert_not_reached ("16-bit integers differ!");
893 
894  if (our_uint16 != 0x123)
895  _dbus_assert_not_reached ("16-bit uints differ!");
896 
897  if (our_int != -0x12345678)
898  _dbus_assert_not_reached ("integers differ!");
899 
900  if (our_uint != 0x12300042)
901  _dbus_assert_not_reached ("uints differ!");
902 
903 #ifdef DBUS_HAVE_INT64
904  if (our_int64 != DBUS_INT64_CONSTANT (-0x123456789abcd))
905  _dbus_assert_not_reached ("64-bit integers differ!");
906  if (our_uint64 != DBUS_UINT64_CONSTANT (0x123456789abcd))
907  _dbus_assert_not_reached ("64-bit unsigned integers differ!");
908 #endif
909 
910  v_DOUBLE = 3.14159;
911  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double, v_DOUBLE))
912  _dbus_assert_not_reached ("doubles differ!");
913 
914  if (strcmp (our_str, "Test string") != 0)
915  _dbus_assert_not_reached ("strings differ!");
916 
917  if (!our_bool)
918  _dbus_assert_not_reached ("booleans differ");
919 
920  if (our_byte_1 != 42)
921  _dbus_assert_not_reached ("bytes differ!");
922 
923  if (our_byte_2 != 24)
924  _dbus_assert_not_reached ("bytes differ!");
925 
926  if (our_uint32_array_len != 4 ||
927  our_uint32_array[0] != 0x12345678 ||
928  our_uint32_array[1] != 0x23456781 ||
929  our_uint32_array[2] != 0x34567812 ||
930  our_uint32_array[3] != 0x45678123)
931  _dbus_assert_not_reached ("uint array differs");
932 
933  if (our_int32_array_len != 4 ||
934  our_int32_array[0] != 0x12345678 ||
935  our_int32_array[1] != -0x23456781 ||
936  our_int32_array[2] != 0x34567812 ||
937  our_int32_array[3] != -0x45678123)
938  _dbus_assert_not_reached ("int array differs");
939 
940 #ifdef DBUS_HAVE_INT64
941  if (our_uint64_array_len != 4 ||
942  our_uint64_array[0] != 0x12345678 ||
943  our_uint64_array[1] != 0x23456781 ||
944  our_uint64_array[2] != 0x34567812 ||
945  our_uint64_array[3] != 0x45678123)
946  _dbus_assert_not_reached ("uint64 array differs");
947 
948  if (our_int64_array_len != 4 ||
949  our_int64_array[0] != 0x12345678 ||
950  our_int64_array[1] != -0x23456781 ||
951  our_int64_array[2] != 0x34567812 ||
952  our_int64_array[3] != -0x45678123)
953  _dbus_assert_not_reached ("int64 array differs");
954 #endif /* DBUS_HAVE_INT64 */
955 
956  if (our_double_array_len != 3)
957  _dbus_assert_not_reached ("double array had wrong length");
958 
959  /* On all IEEE machines (i.e. everything sane) exact equality
960  * should be preserved over the wire
961  */
962  v_DOUBLE = 0.1234;
963  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[0], v_DOUBLE))
964  _dbus_assert_not_reached ("double array had wrong values");
965  v_DOUBLE = 9876.54321;
966  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[1], v_DOUBLE))
967  _dbus_assert_not_reached ("double array had wrong values");
968  v_DOUBLE = -300.0;
969  if (! _DBUS_DOUBLES_BITWISE_EQUAL (our_double_array[2], v_DOUBLE))
970  _dbus_assert_not_reached ("double array had wrong values");
971 
972  if (our_byte_array_len != 4)
973  _dbus_assert_not_reached ("byte array had wrong length");
974 
975  if (our_byte_array[0] != 'a' ||
976  our_byte_array[1] != 'b' ||
977  our_byte_array[2] != 'c' ||
978  our_byte_array[3] != 234)
979  _dbus_assert_not_reached ("byte array had wrong values");
980 
981  if (our_boolean_array_len != 5)
982  _dbus_assert_not_reached ("bool array had wrong length");
983 
984  if (our_boolean_array[0] != TRUE ||
985  our_boolean_array[1] != FALSE ||
986  our_boolean_array[2] != TRUE ||
987  our_boolean_array[3] != TRUE ||
988  our_boolean_array[4] != FALSE)
989  _dbus_assert_not_reached ("bool array had wrong values");
990 
991  if (our_string_array_len != 4)
992  _dbus_assert_not_reached ("string array was wrong length");
993 
994  if (strcmp (our_string_array[0], "Foo") != 0 ||
995  strcmp (our_string_array[1], "bar") != 0 ||
996  strcmp (our_string_array[2], "") != 0 ||
997  strcmp (our_string_array[3], "woo woo woo woo") != 0)
998  _dbus_assert_not_reached ("string array had wrong values");
999 
1000  dbus_free_string_array (our_string_array);
1001 
1002  if (dbus_message_iter_next (&iter))
1003  _dbus_assert_not_reached ("Didn't reach end of arguments");
1004 }
1005 
1013 _dbus_message_test (const char *test_data_dir)
1014 {
1015  DBusMessage *message, *message_without_unix_fds;
1016  DBusMessageLoader *loader;
1017  int i;
1018  const char *data;
1019  DBusMessage *copy;
1020  const char *name1;
1021  const char *name2;
1022  const dbus_uint32_t our_uint32_array[] =
1023  { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
1024  const dbus_int32_t our_int32_array[] =
1025  { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
1026  const dbus_uint32_t *v_ARRAY_UINT32 = our_uint32_array;
1027  const dbus_int32_t *v_ARRAY_INT32 = our_int32_array;
1028 #ifdef DBUS_HAVE_INT64
1029  const dbus_uint64_t our_uint64_array[] =
1030  { 0x12345678, 0x23456781, 0x34567812, 0x45678123 };
1031  const dbus_int64_t our_int64_array[] =
1032  { 0x12345678, -0x23456781, 0x34567812, -0x45678123 };
1033  const dbus_uint64_t *v_ARRAY_UINT64 = our_uint64_array;
1034  const dbus_int64_t *v_ARRAY_INT64 = our_int64_array;
1035 #endif
1036  const char *our_string_array[] = { "Foo", "bar", "", "woo woo woo woo" };
1037  const char **v_ARRAY_STRING = our_string_array;
1038  const double our_double_array[] = { 0.1234, 9876.54321, -300.0 };
1039  const double *v_ARRAY_DOUBLE = our_double_array;
1040  const unsigned char our_byte_array[] = { 'a', 'b', 'c', 234 };
1041  const unsigned char *v_ARRAY_BYTE = our_byte_array;
1042  const dbus_bool_t our_boolean_array[] = { TRUE, FALSE, TRUE, TRUE, FALSE };
1043  const dbus_bool_t *v_ARRAY_BOOLEAN = our_boolean_array;
1044  char sig[64];
1045  const char *s;
1046  const char *v_STRING;
1047  double v_DOUBLE;
1048  dbus_int16_t v_INT16;
1049  dbus_uint16_t v_UINT16;
1050  dbus_int32_t v_INT32;
1051  dbus_uint32_t v_UINT32;
1052 #ifdef DBUS_HAVE_INT64
1053  dbus_int64_t v_INT64;
1054  dbus_uint64_t v_UINT64;
1055 #endif
1056  unsigned char v_BYTE;
1057  unsigned char v2_BYTE;
1058  dbus_bool_t v_BOOLEAN;
1059  DBusMessageIter iter, array_iter, struct_iter;
1060 #ifdef HAVE_UNIX_FD_PASSING
1061  int v_UNIX_FD;
1062 #endif
1063  char **decomposed;
1064  DBusInitialFDs *initial_fds;
1065 
1066  initial_fds = _dbus_check_fdleaks_enter ();
1067 
1068  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1069  "/org/freedesktop/TestPath",
1070  "Foo.TestInterface",
1071  "TestMethod");
1072  _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
1073  _dbus_assert (dbus_message_is_method_call (message, "Foo.TestInterface",
1074  "TestMethod"));
1075  _dbus_assert (strcmp (dbus_message_get_path (message),
1076  "/org/freedesktop/TestPath") == 0);
1077  dbus_message_set_serial (message, 1234);
1078 
1079  /* string length including nul byte not a multiple of 4 */
1080  if (!dbus_message_set_sender (message, "org.foo.bar1"))
1081  _dbus_assert_not_reached ("out of memory");
1082 
1083  _dbus_assert (dbus_message_has_sender (message, "org.foo.bar1"));
1084  dbus_message_set_reply_serial (message, 5678);
1085 
1087  _dbus_string_get_length (&message->header.data));
1088  _dbus_verbose_bytes_of_string (&message->body, 0,
1089  _dbus_string_get_length (&message->body));
1090 
1091  if (!dbus_message_set_sender (message, NULL))
1092  _dbus_assert_not_reached ("out of memory");
1093 
1094 
1096  _dbus_string_get_length (&message->header.data));
1097  _dbus_verbose_bytes_of_string (&message->body, 0,
1098  _dbus_string_get_length (&message->body));
1099 
1100 
1101  _dbus_assert (!dbus_message_has_sender (message, "org.foo.bar1"));
1102  _dbus_assert (dbus_message_get_serial (message) == 1234);
1103  _dbus_assert (dbus_message_get_reply_serial (message) == 5678);
1104  _dbus_assert (dbus_message_has_destination (message, "org.freedesktop.DBus.TestService"));
1105 
1107  dbus_message_set_no_reply (message, TRUE);
1109  dbus_message_set_no_reply (message, FALSE);
1111 
1112  /* Set/get some header fields */
1113 
1114  if (!dbus_message_set_path (message, "/foo"))
1115  _dbus_assert_not_reached ("out of memory");
1116  _dbus_assert (strcmp (dbus_message_get_path (message),
1117  "/foo") == 0);
1118 
1119  if (!dbus_message_set_interface (message, "org.Foo"))
1120  _dbus_assert_not_reached ("out of memory");
1121  _dbus_assert (strcmp (dbus_message_get_interface (message),
1122  "org.Foo") == 0);
1123 
1124  if (!dbus_message_set_member (message, "Bar"))
1125  _dbus_assert_not_reached ("out of memory");
1126  _dbus_assert (strcmp (dbus_message_get_member (message),
1127  "Bar") == 0);
1128 
1129  /* Set/get them with longer values */
1130  if (!dbus_message_set_path (message, "/foo/bar"))
1131  _dbus_assert_not_reached ("out of memory");
1132  _dbus_assert (strcmp (dbus_message_get_path (message),
1133  "/foo/bar") == 0);
1134 
1135  if (!dbus_message_set_interface (message, "org.Foo.Bar"))
1136  _dbus_assert_not_reached ("out of memory");
1137  _dbus_assert (strcmp (dbus_message_get_interface (message),
1138  "org.Foo.Bar") == 0);
1139 
1140  if (!dbus_message_set_member (message, "BarFoo"))
1141  _dbus_assert_not_reached ("out of memory");
1142  _dbus_assert (strcmp (dbus_message_get_member (message),
1143  "BarFoo") == 0);
1144 
1145  /* Realloc shorter again */
1146 
1147  if (!dbus_message_set_path (message, "/foo"))
1148  _dbus_assert_not_reached ("out of memory");
1149  _dbus_assert (strcmp (dbus_message_get_path (message),
1150  "/foo") == 0);
1151 
1152  if (!dbus_message_set_interface (message, "org.Foo"))
1153  _dbus_assert_not_reached ("out of memory");
1154  _dbus_assert (strcmp (dbus_message_get_interface (message),
1155  "org.Foo") == 0);
1156 
1157  if (!dbus_message_set_member (message, "Bar"))
1158  _dbus_assert_not_reached ("out of memory");
1159  _dbus_assert (strcmp (dbus_message_get_member (message),
1160  "Bar") == 0);
1161 
1162  /* Path decomposing */
1163  dbus_message_set_path (message, NULL);
1164  dbus_message_get_path_decomposed (message, &decomposed);
1165  _dbus_assert (decomposed == NULL);
1166  dbus_free_string_array (decomposed);
1167 
1168  dbus_message_set_path (message, "/");
1169  dbus_message_get_path_decomposed (message, &decomposed);
1170  _dbus_assert (decomposed != NULL);
1171  _dbus_assert (decomposed[0] == NULL);
1172  dbus_free_string_array (decomposed);
1173 
1174  dbus_message_set_path (message, "/a/b");
1175  dbus_message_get_path_decomposed (message, &decomposed);
1176  _dbus_assert (decomposed != NULL);
1177  _dbus_assert (strcmp (decomposed[0], "a") == 0);
1178  _dbus_assert (strcmp (decomposed[1], "b") == 0);
1179  _dbus_assert (decomposed[2] == NULL);
1180  dbus_free_string_array (decomposed);
1181 
1182  dbus_message_set_path (message, "/spam/eggs");
1183  dbus_message_get_path_decomposed (message, &decomposed);
1184  _dbus_assert (decomposed != NULL);
1185  _dbus_assert (strcmp (decomposed[0], "spam") == 0);
1186  _dbus_assert (strcmp (decomposed[1], "eggs") == 0);
1187  _dbus_assert (decomposed[2] == NULL);
1188  dbus_free_string_array (decomposed);
1189 
1190  dbus_message_unref (message);
1191 
1192  /* Test the vararg functions */
1193  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1194  "/org/freedesktop/TestPath",
1195  "Foo.TestInterface",
1196  "TestMethod");
1197  dbus_message_set_serial (message, 1);
1198  dbus_message_set_reply_serial (message, 5678);
1199 
1200  v_INT16 = -0x123;
1201  v_UINT16 = 0x123;
1202  v_INT32 = -0x12345678;
1203  v_UINT32 = 0x12300042;
1204 #ifdef DBUS_HAVE_INT64
1205  v_INT64 = DBUS_INT64_CONSTANT (-0x123456789abcd);
1206  v_UINT64 = DBUS_UINT64_CONSTANT (0x123456789abcd);
1207 #endif
1208  v_STRING = "Test string";
1209  v_DOUBLE = 3.14159;
1210  v_BOOLEAN = TRUE;
1211  v_BYTE = 42;
1212  v2_BYTE = 24;
1213 #ifdef HAVE_UNIX_FD_PASSING
1214  v_UNIX_FD = 1;
1215 #endif
1216 
1217  dbus_message_append_args (message,
1218  DBUS_TYPE_INT16, &v_INT16,
1219  DBUS_TYPE_UINT16, &v_UINT16,
1220  DBUS_TYPE_INT32, &v_INT32,
1221  DBUS_TYPE_UINT32, &v_UINT32,
1222 #ifdef DBUS_HAVE_INT64
1223  DBUS_TYPE_INT64, &v_INT64,
1224  DBUS_TYPE_UINT64, &v_UINT64,
1225 #endif
1226  DBUS_TYPE_STRING, &v_STRING,
1227  DBUS_TYPE_DOUBLE, &v_DOUBLE,
1228  DBUS_TYPE_BOOLEAN, &v_BOOLEAN,
1229  DBUS_TYPE_BYTE, &v_BYTE,
1230  DBUS_TYPE_BYTE, &v2_BYTE,
1231  DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32, &v_ARRAY_UINT32,
1232  _DBUS_N_ELEMENTS (our_uint32_array),
1233  DBUS_TYPE_ARRAY, DBUS_TYPE_INT32, &v_ARRAY_INT32,
1234  _DBUS_N_ELEMENTS (our_int32_array),
1235 #ifdef DBUS_HAVE_INT64
1236  DBUS_TYPE_ARRAY, DBUS_TYPE_UINT64, &v_ARRAY_UINT64,
1237  _DBUS_N_ELEMENTS (our_uint64_array),
1238  DBUS_TYPE_ARRAY, DBUS_TYPE_INT64, &v_ARRAY_INT64,
1239  _DBUS_N_ELEMENTS (our_int64_array),
1240 #endif
1241  DBUS_TYPE_ARRAY, DBUS_TYPE_DOUBLE, &v_ARRAY_DOUBLE,
1242  _DBUS_N_ELEMENTS (our_double_array),
1243  DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &v_ARRAY_BYTE,
1244  _DBUS_N_ELEMENTS (our_byte_array),
1245  DBUS_TYPE_ARRAY, DBUS_TYPE_BOOLEAN, &v_ARRAY_BOOLEAN,
1246  _DBUS_N_ELEMENTS (our_boolean_array),
1247  DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, &v_ARRAY_STRING,
1248  _DBUS_N_ELEMENTS (our_string_array),
1249 
1251 
1252  i = 0;
1253  sig[i++] = DBUS_TYPE_INT16;
1254  sig[i++] = DBUS_TYPE_UINT16;
1255  sig[i++] = DBUS_TYPE_INT32;
1256  sig[i++] = DBUS_TYPE_UINT32;
1257 #ifdef DBUS_HAVE_INT64
1258  sig[i++] = DBUS_TYPE_INT64;
1259  sig[i++] = DBUS_TYPE_UINT64;
1260 #endif
1261  sig[i++] = DBUS_TYPE_STRING;
1262  sig[i++] = DBUS_TYPE_DOUBLE;
1263  sig[i++] = DBUS_TYPE_BOOLEAN;
1264  sig[i++] = DBUS_TYPE_BYTE;
1265  sig[i++] = DBUS_TYPE_BYTE;
1266  sig[i++] = DBUS_TYPE_ARRAY;
1267  sig[i++] = DBUS_TYPE_UINT32;
1268  sig[i++] = DBUS_TYPE_ARRAY;
1269  sig[i++] = DBUS_TYPE_INT32;
1270 #ifdef DBUS_HAVE_INT64
1271  sig[i++] = DBUS_TYPE_ARRAY;
1272  sig[i++] = DBUS_TYPE_UINT64;
1273  sig[i++] = DBUS_TYPE_ARRAY;
1274  sig[i++] = DBUS_TYPE_INT64;
1275 #endif
1276  sig[i++] = DBUS_TYPE_ARRAY;
1277  sig[i++] = DBUS_TYPE_DOUBLE;
1278  sig[i++] = DBUS_TYPE_ARRAY;
1279  sig[i++] = DBUS_TYPE_BYTE;
1280  sig[i++] = DBUS_TYPE_ARRAY;
1281  sig[i++] = DBUS_TYPE_BOOLEAN;
1282  sig[i++] = DBUS_TYPE_ARRAY;
1283  sig[i++] = DBUS_TYPE_STRING;
1284 
1285  message_without_unix_fds = dbus_message_copy(message);
1286  _dbus_assert(message_without_unix_fds);
1287 #ifdef HAVE_UNIX_FD_PASSING
1288  dbus_message_append_args (message,
1289  DBUS_TYPE_UNIX_FD, &v_UNIX_FD,
1291  sig[i++] = DBUS_TYPE_UNIX_FD;
1292 #endif
1293  sig[i++] = DBUS_TYPE_INVALID;
1294 
1295  _dbus_assert (i < (int) _DBUS_N_ELEMENTS (sig));
1296 
1297  _dbus_verbose ("HEADER\n");
1299  _dbus_string_get_length (&message->header.data));
1300  _dbus_verbose ("BODY\n");
1301  _dbus_verbose_bytes_of_string (&message->body, 0,
1302  _dbus_string_get_length (&message->body));
1303 
1304  _dbus_verbose ("Signature expected \"%s\" actual \"%s\"\n",
1305  sig, dbus_message_get_signature (message));
1306 
1307  s = dbus_message_get_signature (message);
1308 
1309  _dbus_assert (dbus_message_has_signature (message, sig));
1310  _dbus_assert (strcmp (s, sig) == 0);
1311 
1312  verify_test_message (message);
1313 
1314  copy = dbus_message_copy (message);
1315 
1318  _dbus_assert (message->header.padding == copy->header.padding);
1319 
1322 
1323  _dbus_assert (_dbus_string_get_length (&message->body) ==
1324  _dbus_string_get_length (&copy->body));
1325 
1326  verify_test_message (copy);
1327 
1328  name1 = dbus_message_get_interface (message);
1329  name2 = dbus_message_get_interface (copy);
1330 
1331  _dbus_assert (strcmp (name1, name2) == 0);
1332 
1333  name1 = dbus_message_get_member (message);
1334  name2 = dbus_message_get_member (copy);
1335 
1336  _dbus_assert (strcmp (name1, name2) == 0);
1337 
1338  dbus_message_unref (copy);
1339 
1340  /* Message loader test */
1341  dbus_message_lock (message);
1342  loader = _dbus_message_loader_new ();
1343 
1344  /* check ref/unref */
1345  _dbus_message_loader_ref (loader);
1346  _dbus_message_loader_unref (loader);
1347 
1348  /* Write the header data one byte at a time */
1349  data = _dbus_string_get_const_data (&message->header.data);
1350  for (i = 0; i < _dbus_string_get_length (&message->header.data); i++)
1351  {
1352  DBusString *buffer;
1353 
1354  _dbus_message_loader_get_buffer (loader, &buffer);
1355  _dbus_string_append_byte (buffer, data[i]);
1356  _dbus_message_loader_return_buffer (loader, buffer, 1);
1357  }
1358 
1359  /* Write the body data one byte at a time */
1360  data = _dbus_string_get_const_data (&message->body);
1361  for (i = 0; i < _dbus_string_get_length (&message->body); i++)
1362  {
1363  DBusString *buffer;
1364 
1365  _dbus_message_loader_get_buffer (loader, &buffer);
1366  _dbus_string_append_byte (buffer, data[i]);
1367  _dbus_message_loader_return_buffer (loader, buffer, 1);
1368  }
1369 
1370 #ifdef HAVE_UNIX_FD_PASSING
1371  {
1372  int *unix_fds;
1373  unsigned n_unix_fds;
1374  /* Write unix fd */
1375  _dbus_message_loader_get_unix_fds(loader, &unix_fds, &n_unix_fds);
1376  _dbus_assert(n_unix_fds > 0);
1377  _dbus_assert(message->n_unix_fds == 1);
1378  unix_fds[0] = _dbus_dup(message->unix_fds[0], NULL);
1379  _dbus_assert(unix_fds[0] >= 0);
1380  _dbus_message_loader_return_unix_fds(loader, unix_fds, 1);
1381  }
1382 #endif
1383 
1384  dbus_message_unref (message);
1385 
1386  /* Now pop back the message */
1388  _dbus_assert_not_reached ("no memory to queue messages");
1389 
1391  _dbus_assert_not_reached ("message loader corrupted");
1392 
1393  message = _dbus_message_loader_pop_message (loader);
1394  if (!message)
1395  _dbus_assert_not_reached ("received a NULL message");
1396 
1397  if (dbus_message_get_reply_serial (message) != 5678)
1398  _dbus_assert_not_reached ("reply serial fields differ");
1399 
1400  dbus_message_unref (message);
1401 
1402  /* ovveride the serial, since it was reset by dbus_message_copy() */
1403  dbus_message_set_serial(message_without_unix_fds, 8901);
1404 
1405  dbus_message_lock (message_without_unix_fds);
1406 
1407  verify_test_message (message_without_unix_fds);
1408 
1409  {
1410  /* Marshal and demarshal the message. */
1411 
1412  DBusMessage *message2;
1413  DBusError error = DBUS_ERROR_INIT;
1414  char *marshalled = NULL;
1415  int len = 0;
1416  char garbage_header[DBUS_MINIMUM_HEADER_SIZE] = "xxx";
1417 
1418  if (!dbus_message_marshal (message_without_unix_fds, &marshalled, &len))
1419  _dbus_assert_not_reached ("failed to marshal message");
1420 
1421  _dbus_assert (len != 0);
1422  _dbus_assert (marshalled != NULL);
1423 
1424  _dbus_assert (dbus_message_demarshal_bytes_needed (marshalled, len) == len);
1425  message2 = dbus_message_demarshal (marshalled, len, &error);
1426 
1427  _dbus_assert (message2 != NULL);
1428  _dbus_assert (!dbus_error_is_set (&error));
1429  verify_test_message (message2);
1430 
1431  dbus_message_unref (message2);
1432  dbus_free (marshalled);
1433 
1434  /* Demarshal invalid message. */
1435 
1436  message2 = dbus_message_demarshal ("invalid", 7, &error);
1437  _dbus_assert (message2 == NULL);
1438  _dbus_assert (dbus_error_is_set (&error));
1439  dbus_error_free (&error);
1440 
1441  /* Demarshal invalid (empty) message. */
1442 
1443  message2 = dbus_message_demarshal ("", 0, &error);
1444  _dbus_assert (message2 == NULL);
1445  _dbus_assert (dbus_error_is_set (&error));
1446  dbus_error_free (&error);
1447 
1448  /* Bytes needed to demarshal empty message: 0 (more) */
1449 
1451 
1452  /* Bytes needed to demarshal invalid message: -1 (error). */
1453 
1455  }
1456 
1457  dbus_message_unref (message_without_unix_fds);
1458  _dbus_message_loader_unref (loader);
1459 
1460  check_memleaks ();
1461  _dbus_check_fdleaks_leave (initial_fds);
1462  initial_fds = _dbus_check_fdleaks_enter ();
1463 
1464  /* Check that we can abandon a container */
1465  message = dbus_message_new_method_call ("org.freedesktop.DBus.TestService",
1466  "/org/freedesktop/TestPath",
1467  "Foo.TestInterface",
1468  "Method");
1469 
1470  dbus_message_iter_init_append (message, &iter);
1471 
1472  _dbus_assert (dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
1477  &array_iter));
1479  NULL, &struct_iter));
1480 
1481  s = "peaches";
1482  _dbus_assert (dbus_message_iter_append_basic (&struct_iter, DBUS_TYPE_STRING,
1483  &s));
1484 
1485  /* uh-oh, error, try and unwind */
1486 
1487  dbus_message_iter_abandon_container (&array_iter, &struct_iter);
1488  dbus_message_iter_abandon_container (&array_iter, &iter);
1489 
1490  dbus_message_unref (message);
1491 
1492  /* Load all the sample messages from the message factory */
1493  {
1494  DBusMessageDataIter diter;
1495  DBusMessageData mdata;
1496  int count;
1497 
1498  reset_validities_seen ();
1499 
1500  count = 0;
1501  _dbus_message_data_iter_init (&diter);
1502 
1503  while (_dbus_message_data_iter_get_and_next (&diter,
1504  &mdata))
1505  {
1506  if (!dbus_internal_do_not_use_try_message_data (&mdata.data,
1507  mdata.expected_validity))
1508  {
1509  _dbus_warn ("expected validity %d and did not get it\n",
1510  mdata.expected_validity);
1511  _dbus_assert_not_reached ("message data failed");
1512  }
1513 
1514  _dbus_message_data_free (&mdata);
1515 
1516  count += 1;
1517  }
1518 
1519  printf ("%d sample messages tested\n", count);
1520 
1521  print_validities_seen (FALSE);
1522  print_validities_seen (TRUE);
1523  }
1524 
1525  check_memleaks ();
1526  _dbus_check_fdleaks_leave (initial_fds);
1527 
1528  /* Now load every message in test_data_dir if we have one */
1529  if (test_data_dir == NULL)
1530  return TRUE;
1531 
1532  initial_fds = _dbus_check_fdleaks_enter ();
1533 
1534  if (!dbus_internal_do_not_use_foreach_message_file (test_data_dir,
1535  (DBusForeachMessageFileFunc)
1536  dbus_internal_do_not_use_try_message_file,
1537  NULL))
1538  _dbus_assert_not_reached ("foreach_message_file test failed");
1539 
1540  _dbus_check_fdleaks_leave (initial_fds);
1541 
1542  return TRUE;
1543 }
1544 
1545 #endif /* DBUS_BUILD_TESTS */
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
#define DBUS_TYPE_UINT16
Type code marking a 16-bit unsigned integer.
Definition: dbus-protocol.h:78
void dbus_message_lock(DBusMessage *message)
Locks a message.
Definition: dbus-message.c:383
const char * message
public error message field
Definition: dbus-errors.h:51
#define NULL
A null pointer, defined appropriately for C or C++.
long _dbus_message_loader_get_max_message_size(DBusMessageLoader *loader)
Gets the maximum allowed message size in bytes.
void dbus_message_set_no_reply(DBusMessage *message, dbus_bool_t no_reply)
Sets a flag indicating that the message does not want a reply; if this flag is set, the other end of the connection may (but is not required to) optimize by not sending method return or error replies.
int dbus_message_iter_get_arg_type(DBusMessageIter *iter)
Returns the argument type of the argument that the message iterator points to.
void dbus_free(void *memory)
Frees a block of memory previously allocated by dbus_malloc() or dbus_malloc0().
Definition: dbus-memory.c:700
void _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader, int *fds, unsigned n_fds)
Returns a buffer obtained from _dbus_message_loader_get_unix_fds().
dbus_uint32_t dbus_message_get_serial(DBusMessage *message)
Returns the serial of a message or 0 if none has been specified.
#define DBUS_STRUCT_BEGIN_CHAR_AS_STRING
DBUS_STRUCT_BEGIN_CHAR as a string literal instead of a int literal
void dbus_message_iter_recurse(DBusMessageIter *iter, DBusMessageIter *sub)
Recurses into a container value when reading values from a message, initializing a sub-iterator to us...
DBusMessage * _dbus_message_loader_pop_message(DBusMessageLoader *loader)
Pops a loaded message (passing ownership of the message to the caller).
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can&#39;t appear in a type string...
void _dbus_directory_close(DBusDirIter *iter)
Closes a directory iteration.
dbus_uint32_t padding
bytes of alignment in header
dbus_bool_t _dbus_message_iter_get_args_valist(DBusMessageIter *iter, DBusError *error, int first_arg_type, va_list var_args)
Implementation of the varargs arg-getting functions.
Definition: dbus-message.c:784
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
DBusString body
Body network data.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_directory_get_next_file(DBusDirIter *iter, DBusString *filename, DBusError *error)
Get next file in the directory.
#define DBUS_ERROR_INIT
Expands to a suitable initializer for a DBusError on the stack.
Definition: dbus-errors.h:62
const char * dbus_message_get_signature(DBusMessage *message)
Gets the type signature of the message, i.e.
void dbus_message_iter_init_append(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for appending arguments to the end of a message.
void dbus_error_free(DBusError *error)
Frees an error that&#39;s been set (or just initialized), then reinitializes the error as in dbus_error_i...
Definition: dbus-errors.c:211
#define DBUS_TYPE_BYTE
Type code marking an 8-bit unsigned integer.
Definition: dbus-protocol.h:66
void _dbus_message_loader_unref(DBusMessageLoader *loader)
Decrements the reference count of the loader and finalizes the loader when the count reaches zero...
DBusString data
Header network data, stored separately from body so we can independently realloc it.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:540
int _dbus_dup(int fd, DBusError *error)
Duplicates a file descriptor.
const char * dbus_message_get_path(DBusMessage *message)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
DBusDirIter * _dbus_directory_open(const DBusString *filename, DBusError *error)
Open a directory to iterate over.
dbus_bool_t _dbus_string_init(DBusString *str)
Initializes a string.
Definition: dbus-string.c:175
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1280
DBusValidity
This is primarily used in unit testing, so we can verify that each invalid message is invalid for the...
DBusMessageIter struct; contains no public fields.
Definition: dbus-message.h:51
#define DBUS_TYPE_DOUBLE
Type code marking an 8-byte double in IEEE 754 format.
Definition: dbus-protocol.h:98
dbus_bool_t dbus_message_iter_init(DBusMessage *message, DBusMessageIter *iter)
Initializes a DBusMessageIter for reading the arguments of the message passed in. ...
dbus_bool_t _dbus_string_ends_with_c_str(const DBusString *a, const char *c_str)
Returns whether a string ends with the given suffix.
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
#define DBUS_TYPE_INT64
Type code marking a 64-bit signed integer.
Definition: dbus-protocol.h:90
Internals of directory iterator.
const char * dbus_message_get_member(DBusMessage *message)
Gets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
Internals of DBusMessage.
dbus_bool_t _dbus_concat_dir_and_file(DBusString *dir, const DBusString *next_component)
Appends the given filename to the given directory.
#define DBUS_MINIMUM_HEADER_SIZE
The smallest header size that can occur.
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_string_init_const(DBusString *str, const char *value)
Initializes a constant string.
Definition: dbus-string.c:190
DBusHeader header
Header network data and associated cache.
dbus_bool_t dbus_message_set_sender(DBusMessage *message, const char *sender)
Sets the message sender.
DBusString data
Buffered data.
_DBUS_GNUC_EXTENSION typedef unsigned long long dbus_uint64_t
A 64-bit unsigned integer on all platforms that support it.
DBusMessageLoader * _dbus_message_loader_ref(DBusMessageLoader *loader)
Increments the reference count of the loader.
dbus_bool_t dbus_message_get_path_decomposed(DBusMessage *message, char ***path)
Gets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitt...
void _dbus_warn(const char *format,...)
Prints a warning message to stderr.
dbus_bool_t dbus_message_set_interface(DBusMessage *message, const char *interface)
Sets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the interface...
dbus_bool_t dbus_message_set_path(DBusMessage *message, const char *object_path)
Sets the object path this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or the one a s...
#define DBUS_TYPE_INT32
Type code marking a 32-bit signed integer.
Definition: dbus-protocol.h:82
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:717
DBusMessageLoader * _dbus_message_loader_new(void)
Creates a new message loader.
Object representing an exception.
Definition: dbus-errors.h:48
_DBUS_GNUC_EXTENSION typedef long long dbus_int64_t
A 64-bit signed integer on all platforms that support it.
dbus_bool_t dbus_message_append_args(DBusMessage *message, int first_arg_type,...)
Appends fields to a message given a variable argument list.
#define DBUS_TYPE_UINT64
Type code marking a 64-bit unsigned integer.
Definition: dbus-protocol.h:94
dbus_uint32_t dbus_message_get_reply_serial(DBusMessage *message)
Returns the serial that the message is a reply to or 0 if none.
dbus_bool_t dbus_message_has_signature(DBusMessage *message, const char *signature)
Checks whether the message has the given signature; see dbus_message_get_signature() for more details...
dbus_bool_t _dbus_message_loader_get_is_corrupted(DBusMessageLoader *loader)
Checks whether the loader is confused due to bad data.
#define _DBUS_N_ELEMENTS(array)
Computes the number of elements in a fixed-size array using sizeof().
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
the data is valid
dbus_bool_t dbus_message_has_destination(DBusMessage *message, const char *name)
Checks whether the message was sent to the given name.
short dbus_int16_t
A 16-bit signed integer on all platforms.
dbus_bool_t _dbus_string_append_byte(DBusString *str, unsigned char byte)
Appends a single byte to the string, returning FALSE if not enough memory.
Definition: dbus-string.c:1154
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:242
#define TRUE
Expands to &quot;1&quot;.
dbus_bool_t dbus_message_marshal(DBusMessage *msg, char **marshalled_data_p, int *len_p)
Turn a DBusMessage into the marshalled form as described in the D-Bus specification.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
DBusMessage * dbus_message_copy(const DBusMessage *message)
Creates a new message that is an exact replica of the message specified, except that its refcount is ...
int dbus_message_iter_get_element_type(DBusMessageIter *iter)
Returns the element type of the array that the message iterator points to.
dbus_bool_t dbus_message_is_method_call(DBusMessage *message, const char *interface, const char *method)
Checks whether the message is a method call with the given interface and member fields.
const char * name
public error name field
Definition: dbus-errors.h:50
DBusMessage * dbus_message_demarshal(const char *str, int len, DBusError *error)
Demarshal a D-Bus message from the format described in the D-Bus specification.
#define DBUS_TYPE_UNIX_FD
Type code marking a unix file descriptor.
void _dbus_message_loader_return_buffer(DBusMessageLoader *loader, DBusString *buffer, int bytes_read)
Returns a buffer obtained from _dbus_message_loader_get_buffer(), indicating to the loader how many b...
const char * dbus_message_get_interface(DBusMessage *message)
Gets the interface this message is being sent to (for DBUS_MESSAGE_TYPE_METHOD_CALL) or being emitted...
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
dbus_bool_t dbus_message_set_reply_serial(DBusMessage *message, dbus_uint32_t reply_serial)
Sets the reply serial of a message (the serial of the message this is a reply to).
dbus_bool_t dbus_message_has_sender(DBusMessage *message, const char *name)
Checks whether the message has the given unique name as its sender.
dbus_bool_t dbus_message_iter_next(DBusMessageIter *iter)
Moves the iterator to the next field, if any.
#define DBUS_INT64_CONSTANT(val)
Declare a 64-bit signed integer constant.
dbus_bool_t dbus_message_get_no_reply(DBusMessage *message)
Returns TRUE if the message does not expect a reply.
#define DBUS_TYPE_INT16
Type code marking a 16-bit signed integer.
Definition: dbus-protocol.h:74
dbus_bool_t _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader, int **fds, unsigned *max_n_fds)
Gets the buffer to use for reading unix fds from the network.
void dbus_free_string_array(char **str_array)
Frees a NULL-terminated array of strings.
Definition: dbus-memory.c:748
#define DBUS_TYPE_BOOLEAN
Type code marking a boolean.
Definition: dbus-protocol.h:70
void _dbus_message_loader_get_buffer(DBusMessageLoader *loader, DBusString **buffer)
Gets the buffer to use for reading data from the network.
#define DBUS_STRUCT_END_CHAR_AS_STRING
DBUS_STRUCT_END_CHAR a string literal instead of a int literal
#define DBUS_HAVE_INT64
Defined if 64-bit integers are available.
dbus_bool_t dbus_message_iter_open_container(DBusMessageIter *iter, int type, const char *contained_signature, DBusMessageIter *sub)
Appends a container-typed value to the message; you are required to append the contents of the contai...
dbus_bool_t _dbus_file_get_contents(DBusString *str, const DBusString *filename, DBusError *error)
Appends the contents of the given file to the string, returning error code.
#define DBUS_TYPE_STRING_AS_STRING
DBUS_TYPE_STRING as a string literal instead of a int literal
dbus_bool_t dbus_message_iter_append_basic(DBusMessageIter *iter, int type, const void *value)
Appends a basic-typed value to the message.
void dbus_shutdown(void)
Frees all memory allocated internally by libdbus and reverses the effects of dbus_threads_init().
Definition: dbus-memory.c:879
#define FALSE
Expands to &quot;0&quot;.
int dbus_message_demarshal_bytes_needed(const char *buf, int len)
Returns the number of bytes required to be in the buffer to demarshal a D-Bus message.
void dbus_message_iter_abandon_container(DBusMessageIter *iter, DBusMessageIter *sub)
Abandons creation of a contained-typed value and frees resources created by dbus_message_iter_open_co...
void _dbus_verbose_bytes_of_string(const DBusString *str, int start, int len)
Dump the given part of the string to verbose log.
dbus_bool_t _dbus_message_loader_queue_messages(DBusMessageLoader *loader)
Converts buffered data into messages, if we have enough data.
int dbus_int32_t
A 32-bit signed integer on all platforms.
#define DBUS_UINT64_CONSTANT(val)
Declare a 64-bit unsigned integer constant.
DBusValidity corruption_reason
why we were corrupted
dbus_bool_t dbus_message_set_member(DBusMessage *message, const char *member)
Sets the interface member being invoked (DBUS_MESSAGE_TYPE_METHOD_CALL) or emitted (DBUS_MESSAGE_TYPE...
const char * _dbus_string_get_const_data(const DBusString *str)
Gets the raw character buffer from a const string.
Definition: dbus-string.c:446
void dbus_message_unref(DBusMessage *message)
Decrements the reference count of a DBusMessage, freeing the message if the count reaches 0...
Implementation details of DBusMessageLoader.
DBusMessage * dbus_message_new_method_call(const char *destination, const char *path, const char *interface, const char *method)
Constructs a new message to invoke a method on a remote object.
dbus_bool_t dbus_error_is_set(const DBusError *error)
Checks whether an error occurred (the error is set).
Definition: dbus-errors.c:329
#define _DBUS_DOUBLES_BITWISE_EQUAL(a, b)
On x86 there is an 80-bit FPU, and if you do &quot;a == b&quot; it may have a or b in an 80-bit register...
Definition: dbus-sysdeps.h:476
void dbus_message_set_serial(DBusMessage *message, dbus_uint32_t serial)
Sets the serial number of a message.
Definition: dbus-message.c:253
unsigned short dbus_uint16_t
A 16-bit unsigned integer on all platforms.