D-Bus  1.12.16
dbus-message.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-message.c DBusMessage object
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-marshal-recursive.h"
28 #include "dbus-marshal-validate.h"
29 #include "dbus-marshal-byteswap.h"
30 #include "dbus-marshal-header.h"
31 #include "dbus-signature.h"
32 #include "dbus-message-private.h"
33 #include "dbus-object-tree.h"
34 #include "dbus-memory.h"
35 #include "dbus-list.h"
36 #include "dbus-threads-internal.h"
37 #ifdef HAVE_UNIX_FD_PASSING
38 #include "dbus-sysdeps.h"
39 #include "dbus-sysdeps-unix.h"
40 #endif
41 
42 #include <string.h>
43 
44 #define _DBUS_TYPE_IS_STRINGLIKE(type) \
45  (type == DBUS_TYPE_STRING || type == DBUS_TYPE_SIGNATURE || \
46  type == DBUS_TYPE_OBJECT_PATH)
47 
48 static void dbus_message_finalize (DBusMessage *message);
49 
60 #ifdef DBUS_ENABLE_EMBEDDED_TESTS
61 static dbus_bool_t
62 _dbus_enable_message_cache (void)
63 {
64  static int enabled = -1;
65 
66  if (enabled < 0)
67  {
68  const char *s = _dbus_getenv ("DBUS_MESSAGE_CACHE");
69 
70  enabled = TRUE;
71 
72  if (s && *s)
73  {
74  if (*s == '0')
75  enabled = FALSE;
76  else if (*s == '1')
77  enabled = TRUE;
78  else
79  _dbus_warn ("DBUS_MESSAGE_CACHE should be 0 or 1 if set, not '%s'",
80  s);
81  }
82  }
83 
84  return enabled;
85 }
86 #else
87  /* constant expression, should be optimized away */
88 # define _dbus_enable_message_cache() (TRUE)
89 #endif
90 
91 #ifndef _dbus_message_trace_ref
92 void
93 _dbus_message_trace_ref (DBusMessage *message,
94  int old_refcount,
95  int new_refcount,
96  const char *why)
97 {
98  static int enabled = -1;
99 
100  _dbus_trace_ref ("DBusMessage", message, old_refcount, new_refcount, why,
101  "DBUS_MESSAGE_TRACE", &enabled);
102 }
103 #endif
104 
105 /* Not thread locked, but strictly const/read-only so should be OK
106  */
108 _DBUS_STRING_DEFINE_STATIC(_dbus_empty_signature_str, "");
109 
110 /* these have wacky values to help trap uninitialized iterators;
111  * but has to fit in 3 bits
112  */
113 enum {
114  DBUS_MESSAGE_ITER_TYPE_READER = 3,
115  DBUS_MESSAGE_ITER_TYPE_WRITER = 7
116 };
117 
120 
127 {
132  union
133  {
136  } u;
137 };
138 
144 typedef struct
145 {
146  void *dummy1;
147  void *dummy2;
148  dbus_uint32_t dummy3;
149  int dummy4;
150  int dummy5;
151  int dummy6;
152  int dummy7;
153  int dummy8;
154  int dummy9;
155  int dummy10;
156  int dummy11;
157  int pad1;
158  int pad2;
159  void *pad3;
161 
162 static void
163 get_const_signature (DBusHeader *header,
164  const DBusString **type_str_p,
165  int *type_pos_p)
166 {
167  if (_dbus_header_get_field_raw (header,
169  type_str_p,
170  type_pos_p))
171  {
172  *type_pos_p += 1; /* skip the signature length which is 1 byte */
173  }
174  else
175  {
176  *type_str_p = &_dbus_empty_signature_str;
177  *type_pos_p = 0;
178  }
179 }
180 
186 static void
187 _dbus_message_byteswap (DBusMessage *message)
188 {
189  const DBusString *type_str;
190  int type_pos;
191  char byte_order;
192 
193  byte_order = _dbus_header_get_byte_order (&message->header);
194 
195  if (byte_order == DBUS_COMPILER_BYTE_ORDER)
196  return;
197 
198  _dbus_verbose ("Swapping message into compiler byte order\n");
199 
200  get_const_signature (&message->header, &type_str, &type_pos);
201 
202  _dbus_marshal_byteswap (type_str, type_pos,
203  byte_order,
204  DBUS_COMPILER_BYTE_ORDER,
205  &message->body, 0);
206 
207  _dbus_header_byteswap (&message->header, DBUS_COMPILER_BYTE_ORDER);
209  DBUS_COMPILER_BYTE_ORDER);
210 }
211 
218 #define ensure_byte_order(message) _dbus_message_byteswap (message)
219 
230 void
232  const DBusString **header,
233  const DBusString **body)
234 {
235  _dbus_assert (message->locked);
236 
237  *header = &message->header.data;
238  *body = &message->body;
239 }
240 
251  const int **fds,
252  unsigned *n_fds)
253 {
254  _dbus_assert (message->locked);
255 
256 #ifdef HAVE_UNIX_FD_PASSING
257  *fds = message->unix_fds;
258  *n_fds = message->n_unix_fds;
259 #else
260  *fds = NULL;
261  *n_fds = 0;
262 #endif
263 }
264 
276 void
278  dbus_uint32_t serial)
279 {
280  _dbus_return_if_fail (message != NULL);
281  _dbus_return_if_fail (!message->locked);
282 
283  _dbus_header_set_serial (&message->header, serial);
284 }
285 
302 void
304  DBusList *link)
305 {
306  /* right now we don't recompute the delta when message
307  * size changes, and that's OK for current purposes
308  * I think, but could be important to change later.
309  * Do recompute it whenever there are no outstanding counters,
310  * since it's basically free.
311  */
312  if (message->counters == NULL)
313  {
314  message->size_counter_delta =
315  _dbus_string_get_length (&message->header.data) +
316  _dbus_string_get_length (&message->body);
317 
318 #ifdef HAVE_UNIX_FD_PASSING
319  message->unix_fd_counter_delta = message->n_unix_fds;
320 #endif
321 
322 #if 0
323  _dbus_verbose ("message has size %ld\n",
324  message->size_counter_delta);
325 #endif
326  }
327 
328  _dbus_list_append_link (&message->counters, link);
329 
331 
332 #ifdef HAVE_UNIX_FD_PASSING
333  _dbus_counter_adjust_unix_fd (link->data, message->unix_fd_counter_delta);
334 #endif
335 }
336 
353  DBusCounter *counter)
354 {
355  DBusList *link;
356 
357  link = _dbus_list_alloc_link (counter);
358  if (link == NULL)
359  return FALSE;
360 
361  _dbus_counter_ref (counter);
362  _dbus_message_add_counter_link (message, link);
363 
364  return TRUE;
365 }
366 
374 void
376  DBusCounter *counter)
377 {
378  DBusList *link;
379 
380  link = _dbus_list_find_last (&message->counters,
381  counter);
382  _dbus_assert (link != NULL);
383 
384  _dbus_list_remove_link (&message->counters, link);
385 
386  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
387 
388 #ifdef HAVE_UNIX_FD_PASSING
389  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
390 #endif
391 
392  _dbus_counter_notify (counter);
393  _dbus_counter_unref (counter);
394 }
395 
406 void
408 {
409  if (!message->locked)
410  {
412  _dbus_string_get_length (&message->body));
413 
414  /* must have a signature if you have a body */
415  _dbus_assert (_dbus_string_get_length (&message->body) == 0 ||
416  dbus_message_get_signature (message) != NULL);
417 
418  message->locked = TRUE;
419  }
420 }
421 
422 static dbus_bool_t
423 set_or_delete_string_field (DBusMessage *message,
424  int field,
425  int typecode,
426  const char *value)
427 {
428  if (value == NULL)
429  return _dbus_header_delete_field (&message->header, field);
430  else
431  return _dbus_header_set_field_basic (&message->header,
432  field,
433  typecode,
434  &value);
435 }
436 
437 /* Message Cache
438  *
439  * We cache some DBusMessage to reduce the overhead of allocating
440  * them. In my profiling this consistently made about an 8%
441  * difference. It avoids the malloc for the message, the malloc for
442  * the slot list, the malloc for the header string and body string,
443  * and the associated free() calls. It does introduce another global
444  * lock which could be a performance issue in certain cases.
445  *
446  * For the echo client/server the round trip time goes from around
447  * .000077 to .000069 with the message cache on my laptop. The sysprof
448  * change is as follows (numbers are cumulative percentage):
449  *
450  * with message cache implemented as array as it is now (0.000069 per):
451  * new_empty_header 1.46
452  * mutex_lock 0.56 # i.e. _DBUS_LOCK(message_cache)
453  * mutex_unlock 0.25
454  * self 0.41
455  * unref 2.24
456  * self 0.68
457  * list_clear 0.43
458  * mutex_lock 0.33 # i.e. _DBUS_LOCK(message_cache)
459  * mutex_unlock 0.25
460  *
461  * with message cache implemented as list (0.000070 per roundtrip):
462  * new_empty_header 2.72
463  * list_pop_first 1.88
464  * unref 3.3
465  * list_prepend 1.63
466  *
467  * without cache (0.000077 per roundtrip):
468  * new_empty_header 6.7
469  * string_init_preallocated 3.43
470  * dbus_malloc 2.43
471  * dbus_malloc0 2.59
472  *
473  * unref 4.02
474  * string_free 1.82
475  * dbus_free 1.63
476  * dbus_free 0.71
477  *
478  * If you implement the message_cache with a list, the primary reason
479  * it's slower is that you add another thread lock (on the DBusList
480  * mempool).
481  */
482 
484 #define MAX_MESSAGE_SIZE_TO_CACHE 10 * _DBUS_ONE_KILOBYTE
485 
487 #define MAX_MESSAGE_CACHE_SIZE 5
488 
489 /* Protected by _DBUS_LOCK (message_cache) */
490 static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE];
491 static int message_cache_count = 0;
492 static dbus_bool_t message_cache_shutdown_registered = FALSE;
493 
494 static void
495 dbus_message_cache_shutdown (void *data)
496 {
497  int i;
498 
499  if (!_DBUS_LOCK (message_cache))
500  _dbus_assert_not_reached ("we would have initialized global locks "
501  "before registering a shutdown function");
502 
503  i = 0;
504  while (i < MAX_MESSAGE_CACHE_SIZE)
505  {
506  if (message_cache[i])
507  dbus_message_finalize (message_cache[i]);
508 
509  ++i;
510  }
511 
512  message_cache_count = 0;
513  message_cache_shutdown_registered = FALSE;
514 
515  _DBUS_UNLOCK (message_cache);
516 }
517 
525 static DBusMessage*
526 dbus_message_get_cached (void)
527 {
528  DBusMessage *message;
529  int i;
530 
531  message = NULL;
532 
533  if (!_DBUS_LOCK (message_cache))
534  {
535  /* we'd have initialized global locks before caching anything,
536  * so there can't be anything in the cache */
537  return NULL;
538  }
539 
540  _dbus_assert (message_cache_count >= 0);
541 
542  if (message_cache_count == 0)
543  {
544  _DBUS_UNLOCK (message_cache);
545  return NULL;
546  }
547 
548  /* This is not necessarily true unless count > 0, and
549  * message_cache is uninitialized until the shutdown is
550  * registered
551  */
552  _dbus_assert (message_cache_shutdown_registered);
553 
554  i = 0;
555  while (i < MAX_MESSAGE_CACHE_SIZE)
556  {
557  if (message_cache[i])
558  {
559  message = message_cache[i];
560  message_cache[i] = NULL;
561  message_cache_count -= 1;
562  break;
563  }
564  ++i;
565  }
566  _dbus_assert (message_cache_count >= 0);
568  _dbus_assert (message != NULL);
569 
570  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
571 
572  _dbus_assert (message->counters == NULL);
573 
574  _DBUS_UNLOCK (message_cache);
575 
576  return message;
577 }
578 
579 #ifdef HAVE_UNIX_FD_PASSING
580 static void
581 close_unix_fds(int *fds, unsigned *n_fds)
582 {
583  DBusError e;
584  unsigned int i;
585 
586  if (*n_fds <= 0)
587  return;
588 
589  dbus_error_init(&e);
590 
591  for (i = 0; i < *n_fds; i++)
592  {
593  if (!_dbus_close(fds[i], &e))
594  {
595  _dbus_warn("Failed to close file descriptor: %s", e.message);
596  dbus_error_free(&e);
597  }
598  }
599 
600  *n_fds = 0;
601 
602  /* We don't free the array here, in case we can recycle it later */
603 }
604 #endif
605 
606 static void
607 free_counter (void *element,
608  void *data)
609 {
610  DBusCounter *counter = element;
611  DBusMessage *message = data;
612 
613  _dbus_counter_adjust_size (counter, - message->size_counter_delta);
614 #ifdef HAVE_UNIX_FD_PASSING
615  _dbus_counter_adjust_unix_fd (counter, - message->unix_fd_counter_delta);
616 #endif
617 
618  _dbus_counter_notify (counter);
619  _dbus_counter_unref (counter);
620 }
621 
627 static void
628 dbus_message_cache_or_finalize (DBusMessage *message)
629 {
630  dbus_bool_t was_cached;
631  int i;
632 
633  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
634 
635  /* This calls application code and has to be done first thing
636  * without holding the lock
637  */
639 
640  _dbus_list_foreach (&message->counters,
641  free_counter, message);
642  _dbus_list_clear (&message->counters);
643 
644 #ifdef HAVE_UNIX_FD_PASSING
645  close_unix_fds(message->unix_fds, &message->n_unix_fds);
646 #endif
647 
648  was_cached = FALSE;
649 
650  if (!_DBUS_LOCK (message_cache))
651  {
652  /* The only way to get a non-null message goes through
653  * dbus_message_get_cached() which takes the lock. */
654  _dbus_assert_not_reached ("we would have initialized global locks "
655  "the first time we constructed a message");
656  }
657 
658  if (!message_cache_shutdown_registered)
659  {
660  _dbus_assert (message_cache_count == 0);
661 
662  if (!_dbus_register_shutdown_func (dbus_message_cache_shutdown, NULL))
663  goto out;
664 
665  i = 0;
666  while (i < MAX_MESSAGE_CACHE_SIZE)
667  {
668  message_cache[i] = NULL;
669  ++i;
670  }
671 
672  message_cache_shutdown_registered = TRUE;
673  }
674 
675  _dbus_assert (message_cache_count >= 0);
676 
677  if (!_dbus_enable_message_cache ())
678  goto out;
679 
680  if ((_dbus_string_get_length (&message->header.data) +
681  _dbus_string_get_length (&message->body)) >
683  goto out;
684 
685  if (message_cache_count >= MAX_MESSAGE_CACHE_SIZE)
686  goto out;
687 
688  /* Find empty slot */
689  i = 0;
690  while (message_cache[i] != NULL)
691  ++i;
692 
694 
695  _dbus_assert (message_cache[i] == NULL);
696  message_cache[i] = message;
697  message_cache_count += 1;
698  was_cached = TRUE;
699 #ifndef DBUS_DISABLE_CHECKS
700  message->in_cache = TRUE;
701 #endif
702 
703  out:
704  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
705 
706  _DBUS_UNLOCK (message_cache);
707 
708  if (!was_cached)
709  dbus_message_finalize (message);
710 }
711 
712 /*
713  * Arrange for iter to be something that _dbus_message_iter_check() would
714  * reject as not a valid iterator.
715  */
716 static void
717 _dbus_message_real_iter_zero (DBusMessageRealIter *iter)
718 {
719  _dbus_assert (iter != NULL);
720  _DBUS_ZERO (*iter);
721  /* NULL is not, strictly speaking, guaranteed to be all-bits-zero */
722  iter->message = NULL;
723 }
724 
730 void
732 {
733  _dbus_return_if_fail (iter != NULL);
734  _dbus_message_real_iter_zero ((DBusMessageRealIter *) iter);
735 }
736 
737 static dbus_bool_t
738 _dbus_message_real_iter_is_zeroed (DBusMessageRealIter *iter)
739 {
740  return (iter != NULL && iter->message == NULL && iter->changed_stamp == 0 &&
741  iter->iter_type == 0 && iter->sig_refcount == 0);
742 }
743 
744 #if defined(DBUS_ENABLE_CHECKS) || defined(DBUS_ENABLE_ASSERT)
745 static dbus_bool_t
746 _dbus_message_iter_check (DBusMessageRealIter *iter)
747 {
748  char byte_order;
749 
750  if (iter == NULL)
751  {
752  _dbus_warn_check_failed ("dbus message iterator is NULL");
753  return FALSE;
754  }
755 
756  if (iter->message == NULL || iter->iter_type == 0)
757  {
758  _dbus_warn_check_failed ("dbus message iterator has already been "
759  "closed, or is uninitialized or corrupt");
760  return FALSE;
761  }
762 
763  byte_order = _dbus_header_get_byte_order (&iter->message->header);
764 
765  if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_READER)
766  {
767  if (iter->u.reader.byte_order != byte_order)
768  {
769  _dbus_warn_check_failed ("dbus message changed byte order since iterator was created");
770  return FALSE;
771  }
772  /* because we swap the message into compiler order when you init an iter */
773  _dbus_assert (iter->u.reader.byte_order == DBUS_COMPILER_BYTE_ORDER);
774  }
775  else if (iter->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER)
776  {
777  if (iter->u.writer.byte_order != byte_order)
778  {
779  _dbus_warn_check_failed ("dbus message changed byte order since append iterator was created");
780  return FALSE;
781  }
782  /* because we swap the message into compiler order when you init an iter */
783  _dbus_assert (iter->u.writer.byte_order == DBUS_COMPILER_BYTE_ORDER);
784  }
785  else
786  {
787  _dbus_warn_check_failed ("dbus message iterator looks uninitialized or corrupted");
788  return FALSE;
789  }
790 
791  if (iter->changed_stamp != iter->message->changed_stamp)
792  {
793  _dbus_warn_check_failed ("dbus message iterator invalid because the message has been modified (or perhaps the iterator is just uninitialized)");
794  return FALSE;
795  }
796 
797  return TRUE;
798 }
799 #endif /* DBUS_ENABLE_CHECKS || DBUS_ENABLE_ASSERT */
800 
815  DBusError *error,
816  int first_arg_type,
817  va_list var_args)
818 {
820  int spec_type, msg_type, i, j;
821  dbus_bool_t retval;
822  va_list copy_args;
823 
824  _dbus_assert (_dbus_message_iter_check (real));
825 
826  retval = FALSE;
827 
828  spec_type = first_arg_type;
829  i = 0;
830 
831  /* copy var_args first, then we can do another iteration over it to
832  * free memory and close unix fds if parse failed at some point.
833  */
834  DBUS_VA_COPY (copy_args, var_args);
835 
836  while (spec_type != DBUS_TYPE_INVALID)
837  {
838  msg_type = dbus_message_iter_get_arg_type (iter);
839 
840  if (msg_type != spec_type)
841  {
843  "Argument %d is specified to be of type \"%s\", but "
844  "is actually of type \"%s\"\n", i,
845  _dbus_type_to_string (spec_type),
846  _dbus_type_to_string (msg_type));
847 
848  goto out;
849  }
850 
851  if (spec_type == DBUS_TYPE_UNIX_FD)
852  {
853 #ifdef HAVE_UNIX_FD_PASSING
854  DBusBasicValue idx;
855  int *pfd, nfd;
856 
857  pfd = va_arg (var_args, int*);
858  _dbus_assert(pfd);
859 
860  _dbus_type_reader_read_basic(&real->u.reader, &idx);
861 
862  if (idx.u32 >= real->message->n_unix_fds)
863  {
865  "Message refers to file descriptor at index %i,"
866  "but has only %i descriptors attached.\n",
867  idx.u32,
868  real->message->n_unix_fds);
869  goto out;
870  }
871 
872  if ((nfd = _dbus_dup(real->message->unix_fds[idx.u32], error)) < 0)
873  goto out;
874 
875  *pfd = nfd;
876 #else
878  "Platform does not support file desciptor passing.\n");
879  goto out;
880 #endif
881  }
882  else if (dbus_type_is_basic (spec_type))
883  {
884  DBusBasicValue *ptr;
885 
886  ptr = va_arg (var_args, DBusBasicValue*);
887 
888  _dbus_assert (ptr != NULL);
889 
891  ptr);
892  }
893  else if (spec_type == DBUS_TYPE_ARRAY)
894  {
895  int element_type;
896  int spec_element_type;
897  const DBusBasicValue **ptr;
898  int *n_elements_p;
899  DBusTypeReader array;
900 
901  spec_element_type = va_arg (var_args, int);
902  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
903 
904  if (spec_element_type != element_type)
905  {
907  "Argument %d is specified to be an array of \"%s\", but "
908  "is actually an array of \"%s\"\n",
909  i,
910  _dbus_type_to_string (spec_element_type),
911  _dbus_type_to_string (element_type));
912 
913  goto out;
914  }
915 
916  if (dbus_type_is_fixed (spec_element_type) &&
917  element_type != DBUS_TYPE_UNIX_FD)
918  {
919  ptr = va_arg (var_args, const DBusBasicValue**);
920  n_elements_p = va_arg (var_args, int*);
921 
922  _dbus_assert (ptr != NULL);
923  _dbus_assert (n_elements_p != NULL);
924 
925  _dbus_type_reader_recurse (&real->u.reader, &array);
926 
928  (void *) ptr, n_elements_p);
929  }
930  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
931  {
932  char ***str_array_p;
933  int n_elements;
934  char **str_array;
935 
936  str_array_p = va_arg (var_args, char***);
937  n_elements_p = va_arg (var_args, int*);
938 
939  _dbus_assert (str_array_p != NULL);
940  _dbus_assert (n_elements_p != NULL);
941 
942  /* Count elements in the array */
943  _dbus_type_reader_recurse (&real->u.reader, &array);
944 
945  n_elements = 0;
947  {
948  ++n_elements;
949  _dbus_type_reader_next (&array);
950  }
951 
952  str_array = dbus_new0 (char*, n_elements + 1);
953  if (str_array == NULL)
954  {
955  _DBUS_SET_OOM (error);
956  goto out;
957  }
958 
959  /* Now go through and dup each string */
960  _dbus_type_reader_recurse (&real->u.reader, &array);
961 
962  j = 0;
963  while (j < n_elements)
964  {
965  const char *s;
967  (void *) &s);
968 
969  str_array[j] = _dbus_strdup (s);
970  if (str_array[j] == NULL)
971  {
972  dbus_free_string_array (str_array);
973  _DBUS_SET_OOM (error);
974  goto out;
975  }
976 
977  ++j;
978 
979  if (!_dbus_type_reader_next (&array))
980  _dbus_assert (j == n_elements);
981  }
982 
984  _dbus_assert (j == n_elements);
985  _dbus_assert (str_array[j] == NULL);
986 
987  *str_array_p = str_array;
988  *n_elements_p = n_elements;
989  }
990 #ifndef DBUS_DISABLE_CHECKS
991  else
992  {
993  _dbus_warn ("you can't read arrays of container types (struct, variant, array) with %s for now",
994  _DBUS_FUNCTION_NAME);
995  goto out;
996  }
997 #endif
998  }
999 #ifndef DBUS_DISABLE_CHECKS
1000  else
1001  {
1002  _dbus_warn ("you can only read arrays and basic types with %s for now",
1003  _DBUS_FUNCTION_NAME);
1004  goto out;
1005  }
1006 #endif
1007 
1008  /* how many arguments already handled */
1009  i++;
1010 
1011  spec_type = va_arg (var_args, int);
1012  if (!_dbus_type_reader_next (&real->u.reader) && spec_type != DBUS_TYPE_INVALID)
1013  {
1015  "Message has only %d arguments, but more were expected", i);
1016  goto out;
1017  }
1018  }
1019 
1020  retval = TRUE;
1021 
1022  out:
1023  /* there may memory or unix fd leak in the above iteration if parse failed.
1024  * so we have another iteration over copy_args to free memory and close
1025  * unix fds.
1026  */
1027  if (!retval)
1028  {
1029  spec_type = first_arg_type;
1030  j = 0;
1031 
1032  while (j < i)
1033  {
1034  if (spec_type == DBUS_TYPE_UNIX_FD)
1035  {
1036 #ifdef HAVE_UNIX_FD_PASSING
1037  int *pfd;
1038 
1039  pfd = va_arg (copy_args, int *);
1040  _dbus_assert(pfd);
1041  if (*pfd >= 0)
1042  {
1043  _dbus_close (*pfd, NULL);
1044  *pfd = -1;
1045  }
1046 #endif
1047  }
1048  else if (dbus_type_is_basic (spec_type))
1049  {
1050  /* move the index forward */
1051  va_arg (copy_args, DBusBasicValue *);
1052  }
1053  else if (spec_type == DBUS_TYPE_ARRAY)
1054  {
1055  int spec_element_type;
1056 
1057  spec_element_type = va_arg (copy_args, int);
1058  if (dbus_type_is_fixed (spec_element_type))
1059  {
1060  /* move the index forward */
1061  va_arg (copy_args, const DBusBasicValue **);
1062  va_arg (copy_args, int *);
1063  }
1064  else if (_DBUS_TYPE_IS_STRINGLIKE (spec_element_type))
1065  {
1066  char ***str_array_p;
1067 
1068  str_array_p = va_arg (copy_args, char ***);
1069  /* move the index forward */
1070  va_arg (copy_args, int *);
1071  _dbus_assert (str_array_p != NULL);
1072  dbus_free_string_array (*str_array_p);
1073  *str_array_p = NULL;
1074  }
1075  }
1076 
1077  spec_type = va_arg (copy_args, int);
1078  j++;
1079  }
1080  }
1081 
1082  va_end (copy_args);
1083  return retval;
1084 }
1085 
1146 {
1147  _dbus_return_val_if_fail (message != NULL, 0);
1148 
1149  return _dbus_header_get_serial (&message->header);
1150 }
1151 
1162  dbus_uint32_t reply_serial)
1163 {
1164  DBusBasicValue value;
1165 
1166  _dbus_return_val_if_fail (message != NULL, FALSE);
1167  _dbus_return_val_if_fail (!message->locked, FALSE);
1168  _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
1169 
1170  value.u32 = reply_serial;
1171 
1172  return _dbus_header_set_field_basic (&message->header,
1175  &value);
1176 }
1177 
1186 {
1187  dbus_uint32_t v_UINT32;
1188 
1189  _dbus_return_val_if_fail (message != NULL, 0);
1190 
1191  if (_dbus_header_get_field_basic (&message->header,
1194  &v_UINT32))
1195  return v_UINT32;
1196  else
1197  return 0;
1198 }
1199 
1200 static void
1201 dbus_message_finalize (DBusMessage *message)
1202 {
1203  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1204 
1205  /* This calls application callbacks! */
1207 
1208  _dbus_list_foreach (&message->counters,
1209  free_counter, message);
1210  _dbus_list_clear (&message->counters);
1211 
1212  _dbus_header_free (&message->header);
1213  _dbus_string_free (&message->body);
1214 
1215 #ifdef HAVE_UNIX_FD_PASSING
1216  close_unix_fds(message->unix_fds, &message->n_unix_fds);
1217  dbus_free(message->unix_fds);
1218 #endif
1219 
1220  _dbus_assert (_dbus_atomic_get (&message->refcount) == 0);
1221 
1222  dbus_free (message);
1223 }
1224 
1225 static DBusMessage*
1226 dbus_message_new_empty_header (void)
1227 {
1228  DBusMessage *message;
1229  dbus_bool_t from_cache;
1230 
1231  message = dbus_message_get_cached ();
1232 
1233  if (message != NULL)
1234  {
1235  from_cache = TRUE;
1236  }
1237  else
1238  {
1239  from_cache = FALSE;
1240  message = dbus_new0 (DBusMessage, 1);
1241  if (message == NULL)
1242  return NULL;
1243 #ifndef DBUS_DISABLE_CHECKS
1245 #endif
1246 
1247 #ifdef HAVE_UNIX_FD_PASSING
1248  message->unix_fds = NULL;
1249  message->n_unix_fds_allocated = 0;
1250 #endif
1251  }
1252 
1253  _dbus_atomic_inc (&message->refcount);
1254 
1255  _dbus_message_trace_ref (message, 0, 1, "new_empty_header");
1256 
1257  message->locked = FALSE;
1258 #ifndef DBUS_DISABLE_CHECKS
1259  message->in_cache = FALSE;
1260 #endif
1261  message->counters = NULL;
1262  message->size_counter_delta = 0;
1263  message->changed_stamp = 0;
1264 
1265 #ifdef HAVE_UNIX_FD_PASSING
1266  message->n_unix_fds = 0;
1267  message->n_unix_fds_allocated = 0;
1268  message->unix_fd_counter_delta = 0;
1269 #endif
1270 
1271  if (!from_cache)
1273 
1274  if (from_cache)
1275  {
1276  _dbus_header_reinit (&message->header);
1277  _dbus_string_set_length (&message->body, 0);
1278  }
1279  else
1280  {
1281  if (!_dbus_header_init (&message->header))
1282  {
1283  dbus_free (message);
1284  return NULL;
1285  }
1286 
1287  if (!_dbus_string_init_preallocated (&message->body, 32))
1288  {
1289  _dbus_header_free (&message->header);
1290  dbus_free (message);
1291  return NULL;
1292  }
1293  }
1294 
1295  return message;
1296 }
1297 
1310 DBusMessage*
1311 dbus_message_new (int message_type)
1312 {
1313  DBusMessage *message;
1314 
1315  _dbus_return_val_if_fail (message_type != DBUS_MESSAGE_TYPE_INVALID, NULL);
1316 
1317  message = dbus_message_new_empty_header ();
1318  if (message == NULL)
1319  return NULL;
1320 
1321  if (!_dbus_header_create (&message->header,
1322  DBUS_COMPILER_BYTE_ORDER,
1323  message_type,
1324  NULL, NULL, NULL, NULL, NULL))
1325  {
1326  dbus_message_unref (message);
1327  return NULL;
1328  }
1329 
1330  return message;
1331 }
1332 
1354 DBusMessage*
1355 dbus_message_new_method_call (const char *destination,
1356  const char *path,
1357  const char *iface,
1358  const char *method)
1359 {
1360  DBusMessage *message;
1361 
1362  _dbus_return_val_if_fail (path != NULL, NULL);
1363  _dbus_return_val_if_fail (method != NULL, NULL);
1364  _dbus_return_val_if_fail (destination == NULL ||
1365  _dbus_check_is_valid_bus_name (destination), NULL);
1366  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1367  _dbus_return_val_if_fail (iface == NULL ||
1368  _dbus_check_is_valid_interface (iface), NULL);
1369  _dbus_return_val_if_fail (_dbus_check_is_valid_member (method), NULL);
1370 
1371  message = dbus_message_new_empty_header ();
1372  if (message == NULL)
1373  return NULL;
1374 
1375  if (!_dbus_header_create (&message->header,
1376  DBUS_COMPILER_BYTE_ORDER,
1378  destination, path, iface, method, NULL))
1379  {
1380  dbus_message_unref (message);
1381  return NULL;
1382  }
1383 
1384  return message;
1385 }
1386 
1394 DBusMessage*
1396 {
1397  DBusMessage *message;
1398  const char *sender;
1399 
1400  _dbus_return_val_if_fail (method_call != NULL, NULL);
1401 
1402  sender = dbus_message_get_sender (method_call);
1403 
1404  /* sender is allowed to be null here in peer-to-peer case */
1405 
1406  message = dbus_message_new_empty_header ();
1407  if (message == NULL)
1408  return NULL;
1409 
1410  if (!_dbus_header_create (&message->header,
1411  DBUS_COMPILER_BYTE_ORDER,
1413  sender, NULL, NULL, NULL, NULL))
1414  {
1415  dbus_message_unref (message);
1416  return NULL;
1417  }
1418 
1419  dbus_message_set_no_reply (message, TRUE);
1420 
1421  if (!dbus_message_set_reply_serial (message,
1422  dbus_message_get_serial (method_call)))
1423  {
1424  dbus_message_unref (message);
1425  return NULL;
1426  }
1427 
1428  return message;
1429 }
1430 
1445 DBusMessage*
1446 dbus_message_new_signal (const char *path,
1447  const char *iface,
1448  const char *name)
1449 {
1450  DBusMessage *message;
1451 
1452  _dbus_return_val_if_fail (path != NULL, NULL);
1453  _dbus_return_val_if_fail (iface != NULL, NULL);
1454  _dbus_return_val_if_fail (name != NULL, NULL);
1455  _dbus_return_val_if_fail (_dbus_check_is_valid_path (path), NULL);
1456  _dbus_return_val_if_fail (_dbus_check_is_valid_interface (iface), NULL);
1457  _dbus_return_val_if_fail (_dbus_check_is_valid_member (name), NULL);
1458 
1459  message = dbus_message_new_empty_header ();
1460  if (message == NULL)
1461  return NULL;
1462 
1463  if (!_dbus_header_create (&message->header,
1464  DBUS_COMPILER_BYTE_ORDER,
1466  NULL, path, iface, name, NULL))
1467  {
1468  dbus_message_unref (message);
1469  return NULL;
1470  }
1471 
1472  dbus_message_set_no_reply (message, TRUE);
1473 
1474  return message;
1475 }
1476 
1491 DBusMessage*
1493  const char *error_name,
1494  const char *error_message)
1495 {
1496  DBusMessage *message;
1497  const char *sender;
1498  DBusMessageIter iter;
1499 
1500  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1501  _dbus_return_val_if_fail (error_name != NULL, NULL);
1502  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1503 
1504  sender = dbus_message_get_sender (reply_to);
1505 
1506  /* sender may be NULL for non-message-bus case or
1507  * when the message bus is dealing with an unregistered
1508  * connection.
1509  */
1510  message = dbus_message_new_empty_header ();
1511  if (message == NULL)
1512  return NULL;
1513 
1514  if (!_dbus_header_create (&message->header,
1515  DBUS_COMPILER_BYTE_ORDER,
1517  sender, NULL, NULL, NULL, error_name))
1518  {
1519  dbus_message_unref (message);
1520  return NULL;
1521  }
1522 
1523  dbus_message_set_no_reply (message, TRUE);
1524 
1525  if (!dbus_message_set_reply_serial (message,
1526  dbus_message_get_serial (reply_to)))
1527  {
1528  dbus_message_unref (message);
1529  return NULL;
1530  }
1531 
1532  if (error_message != NULL)
1533  {
1534  dbus_message_iter_init_append (message, &iter);
1535  if (!dbus_message_iter_append_basic (&iter,
1537  &error_message))
1538  {
1539  dbus_message_unref (message);
1540  return NULL;
1541  }
1542  }
1543 
1544  return message;
1545 }
1546 
1563 DBusMessage*
1565  const char *error_name,
1566  const char *error_format,
1567  ...)
1568 {
1569  va_list args;
1570  DBusString str;
1571  DBusMessage *message;
1572 
1573  _dbus_return_val_if_fail (reply_to != NULL, NULL);
1574  _dbus_return_val_if_fail (error_name != NULL, NULL);
1575  _dbus_return_val_if_fail (_dbus_check_is_valid_error_name (error_name), NULL);
1576 
1577  if (!_dbus_string_init (&str))
1578  return NULL;
1579 
1580  va_start (args, error_format);
1581 
1582  if (_dbus_string_append_printf_valist (&str, error_format, args))
1583  message = dbus_message_new_error (reply_to, error_name,
1585  else
1586  message = NULL;
1587 
1588  _dbus_string_free (&str);
1589 
1590  va_end (args);
1591 
1592  return message;
1593 }
1594 
1595 
1608 DBusMessage *
1610 {
1611  DBusMessage *retval;
1612 
1613  _dbus_return_val_if_fail (message != NULL, NULL);
1614 
1615  retval = dbus_new0 (DBusMessage, 1);
1616  if (retval == NULL)
1617  return NULL;
1618 
1619  _dbus_atomic_inc (&retval->refcount);
1620 
1621  retval->locked = FALSE;
1622 #ifndef DBUS_DISABLE_CHECKS
1623  retval->generation = message->generation;
1624 #endif
1625 
1626  if (!_dbus_header_copy (&message->header, &retval->header))
1627  {
1628  dbus_free (retval);
1629  return NULL;
1630  }
1631 
1632  if (!_dbus_string_init_preallocated (&retval->body,
1633  _dbus_string_get_length (&message->body)))
1634  {
1635  _dbus_header_free (&retval->header);
1636  dbus_free (retval);
1637  return NULL;
1638  }
1639 
1640  if (!_dbus_string_copy (&message->body, 0,
1641  &retval->body, 0))
1642  goto failed_copy;
1643 
1644 #ifdef HAVE_UNIX_FD_PASSING
1645  retval->unix_fds = dbus_new(int, message->n_unix_fds);
1646  if (retval->unix_fds == NULL && message->n_unix_fds > 0)
1647  goto failed_copy;
1648 
1649  retval->n_unix_fds_allocated = message->n_unix_fds;
1650 
1651  for (retval->n_unix_fds = 0;
1652  retval->n_unix_fds < message->n_unix_fds;
1653  retval->n_unix_fds++)
1654  {
1655  retval->unix_fds[retval->n_unix_fds] = _dbus_dup(message->unix_fds[retval->n_unix_fds], NULL);
1656 
1657  if (retval->unix_fds[retval->n_unix_fds] < 0)
1658  goto failed_copy;
1659  }
1660 
1661 #endif
1662 
1663  _dbus_message_trace_ref (retval, 0, 1, "copy");
1664  return retval;
1665 
1666  failed_copy:
1667  _dbus_header_free (&retval->header);
1668  _dbus_string_free (&retval->body);
1669 
1670 #ifdef HAVE_UNIX_FD_PASSING
1671  close_unix_fds(retval->unix_fds, &retval->n_unix_fds);
1672  dbus_free(retval->unix_fds);
1673 #endif
1674 
1675  dbus_free (retval);
1676 
1677  return NULL;
1678 }
1679 
1680 
1688 DBusMessage *
1690 {
1691  dbus_int32_t old_refcount;
1692 
1693  _dbus_return_val_if_fail (message != NULL, NULL);
1694  _dbus_return_val_if_fail (message->generation == _dbus_current_generation, NULL);
1695  _dbus_return_val_if_fail (!message->in_cache, NULL);
1696 
1697  old_refcount = _dbus_atomic_inc (&message->refcount);
1698  _dbus_assert (old_refcount >= 1);
1699  _dbus_message_trace_ref (message, old_refcount, old_refcount + 1, "ref");
1700 
1701  return message;
1702 }
1703 
1711 void
1713 {
1714  dbus_int32_t old_refcount;
1715 
1716  _dbus_return_if_fail (message != NULL);
1717  _dbus_return_if_fail (message->generation == _dbus_current_generation);
1718  _dbus_return_if_fail (!message->in_cache);
1719 
1720  old_refcount = _dbus_atomic_dec (&message->refcount);
1721 
1722  _dbus_assert (old_refcount >= 1);
1723 
1724  _dbus_message_trace_ref (message, old_refcount, old_refcount - 1, "unref");
1725 
1726  if (old_refcount == 1)
1727  {
1728  /* Calls application callbacks! */
1729  dbus_message_cache_or_finalize (message);
1730  }
1731 }
1732 
1743 int
1745 {
1746  _dbus_return_val_if_fail (message != NULL, DBUS_MESSAGE_TYPE_INVALID);
1747 
1748  return _dbus_header_get_message_type (&message->header);
1749 }
1750 
1815  int first_arg_type,
1816  ...)
1817 {
1818  dbus_bool_t retval;
1819  va_list var_args;
1820 
1821  _dbus_return_val_if_fail (message != NULL, FALSE);
1822 
1823  va_start (var_args, first_arg_type);
1824  retval = dbus_message_append_args_valist (message,
1825  first_arg_type,
1826  var_args);
1827  va_end (var_args);
1828 
1829  return retval;
1830 }
1831 
1847  int first_arg_type,
1848  va_list var_args)
1849 {
1850  int type;
1851  DBusMessageIter iter;
1852 
1853  _dbus_return_val_if_fail (message != NULL, FALSE);
1854 
1855  type = first_arg_type;
1856 
1857  dbus_message_iter_init_append (message, &iter);
1858 
1859  while (type != DBUS_TYPE_INVALID)
1860  {
1861  if (dbus_type_is_basic (type))
1862  {
1863  const DBusBasicValue *value;
1864  value = va_arg (var_args, const DBusBasicValue*);
1865 
1866  if (!dbus_message_iter_append_basic (&iter,
1867  type,
1868  value))
1869  goto failed;
1870  }
1871  else if (type == DBUS_TYPE_ARRAY)
1872  {
1873  int element_type;
1874  DBusMessageIter array;
1875  char buf[2];
1876 
1877  element_type = va_arg (var_args, int);
1878 
1879  buf[0] = element_type;
1880  buf[1] = '\0';
1883  buf,
1884  &array))
1885  goto failed;
1886 
1887  if (dbus_type_is_fixed (element_type) &&
1888  element_type != DBUS_TYPE_UNIX_FD)
1889  {
1890  const DBusBasicValue **value;
1891  int n_elements;
1892 
1893  value = va_arg (var_args, const DBusBasicValue**);
1894  n_elements = va_arg (var_args, int);
1895 
1897  element_type,
1898  value,
1899  n_elements)) {
1900  dbus_message_iter_abandon_container (&iter, &array);
1901  goto failed;
1902  }
1903  }
1904  else if (_DBUS_TYPE_IS_STRINGLIKE (element_type))
1905  {
1906  const char ***value_p;
1907  const char **value;
1908  int n_elements;
1909  int i;
1910 
1911  value_p = va_arg (var_args, const char***);
1912  n_elements = va_arg (var_args, int);
1913 
1914  value = *value_p;
1915 
1916  i = 0;
1917  while (i < n_elements)
1918  {
1919  if (!dbus_message_iter_append_basic (&array,
1920  element_type,
1921  &value[i])) {
1922  dbus_message_iter_abandon_container (&iter, &array);
1923  goto failed;
1924  }
1925  ++i;
1926  }
1927  }
1928  else
1929  {
1930  _dbus_warn ("arrays of %s can't be appended with %s for now",
1931  _dbus_type_to_string (element_type),
1932  _DBUS_FUNCTION_NAME);
1933  dbus_message_iter_abandon_container (&iter, &array);
1934  goto failed;
1935  }
1936 
1937  if (!dbus_message_iter_close_container (&iter, &array))
1938  goto failed;
1939  }
1940 #ifndef DBUS_DISABLE_CHECKS
1941  else
1942  {
1943  _dbus_warn ("type %s isn't supported yet in %s",
1944  _dbus_type_to_string (type), _DBUS_FUNCTION_NAME);
1945  goto failed;
1946  }
1947 #endif
1948 
1949  type = va_arg (var_args, int);
1950  }
1951 
1952  return TRUE;
1953 
1954  failed:
1955  return FALSE;
1956 }
1957 
2004  DBusError *error,
2005  int first_arg_type,
2006  ...)
2007 {
2008  dbus_bool_t retval;
2009  va_list var_args;
2010 
2011  _dbus_return_val_if_fail (message != NULL, FALSE);
2012  _dbus_return_val_if_error_is_set (error, FALSE);
2013 
2014  va_start (var_args, first_arg_type);
2015  retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
2016  va_end (var_args);
2017 
2018  return retval;
2019 }
2020 
2033  DBusError *error,
2034  int first_arg_type,
2035  va_list var_args)
2036 {
2037  DBusMessageIter iter;
2038 
2039  _dbus_return_val_if_fail (message != NULL, FALSE);
2040  _dbus_return_val_if_error_is_set (error, FALSE);
2041 
2042  dbus_message_iter_init (message, &iter);
2043  return _dbus_message_iter_get_args_valist (&iter, error, first_arg_type, var_args);
2044 }
2045 
2046 static void
2047 _dbus_message_iter_init_common (DBusMessage *message,
2048  DBusMessageRealIter *real,
2049  int iter_type)
2050 {
2051  /* If these static assertions fail on your platform, report it as a bug. */
2052  _DBUS_STATIC_ASSERT (sizeof (DBusMessageRealIter) <= sizeof (DBusMessageIter));
2053  _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageRealIter) <=
2054  _DBUS_ALIGNOF (DBusMessageIter));
2055  /* A failure of these two assertions would indicate that we've broken
2056  * ABI on this platform since 1.10.0. */
2057  _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter_1_10_0) ==
2058  sizeof (DBusMessageIter));
2059  _DBUS_STATIC_ASSERT (_DBUS_ALIGNOF (DBusMessageIter_1_10_0) ==
2060  _DBUS_ALIGNOF (DBusMessageIter));
2061  /* If this static assertion fails, it means the DBusMessageIter struct
2062  * is not "packed", which might result in "iter = other_iter" not copying
2063  * every byte. */
2064  _DBUS_STATIC_ASSERT (sizeof (DBusMessageIter) ==
2065  4 * sizeof (void *) + sizeof (dbus_uint32_t) + 9 * sizeof (int));
2066 
2067  /* Since the iterator will read or write who-knows-what from the
2068  * message, we need to get in the right byte order
2069  */
2070  ensure_byte_order (message);
2071 
2072  real->message = message;
2073  real->changed_stamp = message->changed_stamp;
2074  real->iter_type = iter_type;
2075  real->sig_refcount = 0;
2076 }
2077 
2102  DBusMessageIter *iter)
2103 {
2104  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2105  const DBusString *type_str;
2106  int type_pos;
2107 
2108  _dbus_return_val_if_fail (message != NULL, FALSE);
2109  _dbus_return_val_if_fail (iter != NULL, FALSE);
2110 
2111  get_const_signature (&message->header, &type_str, &type_pos);
2112 
2113  _dbus_message_iter_init_common (message, real,
2114  DBUS_MESSAGE_ITER_TYPE_READER);
2115 
2117  _dbus_header_get_byte_order (&message->header),
2118  type_str, type_pos,
2119  &message->body,
2120  0);
2121 
2123 }
2124 
2133 {
2134  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2135 
2136  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2137  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2138 
2139  return _dbus_type_reader_has_next (&real->u.reader);
2140 }
2141 
2152 {
2153  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2154 
2155  _dbus_return_val_if_fail (_dbus_message_iter_check (real), FALSE);
2156  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2157 
2158  return _dbus_type_reader_next (&real->u.reader);
2159 }
2160 
2175 int
2177 {
2178  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2179 
2180  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2181  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, FALSE);
2182 
2184 }
2185 
2194 int
2196 {
2197  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2198 
2199  _dbus_return_val_if_fail (_dbus_message_iter_check (real), DBUS_TYPE_INVALID);
2200  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_READER, DBUS_TYPE_INVALID);
2201  _dbus_return_val_if_fail (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_ARRAY, DBUS_TYPE_INVALID);
2202 
2204 }
2205 
2231 void
2233  DBusMessageIter *sub)
2234 {
2235  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2236  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2237 
2238  _dbus_return_if_fail (_dbus_message_iter_check (real));
2239  _dbus_return_if_fail (sub != NULL);
2240 
2241  *real_sub = *real;
2242  _dbus_type_reader_recurse (&real->u.reader, &real_sub->u.reader);
2243 }
2244 
2256 char *
2258 {
2259  const DBusString *sig;
2260  DBusString retstr;
2261  char *ret;
2262  int start, len;
2263  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2264 
2265  _dbus_return_val_if_fail (_dbus_message_iter_check (real), NULL);
2266 
2267  if (!_dbus_string_init (&retstr))
2268  return NULL;
2269 
2271  &start, &len);
2272  if (!_dbus_string_append_len (&retstr,
2273  _dbus_string_get_const_data (sig) + start,
2274  len))
2275  return NULL;
2276  if (!_dbus_string_steal_data (&retstr, &ret))
2277  return NULL;
2278  _dbus_string_free (&retstr);
2279  return ret;
2280 }
2281 
2329 void
2331  void *value)
2332 {
2333  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2334 
2335  _dbus_return_if_fail (_dbus_message_iter_check (real));
2336  _dbus_return_if_fail (value != NULL);
2337 
2339  {
2340 #ifdef HAVE_UNIX_FD_PASSING
2341  DBusBasicValue idx;
2342 
2343  _dbus_type_reader_read_basic(&real->u.reader, &idx);
2344 
2345  if (idx.u32 >= real->message->n_unix_fds) {
2346  /* Hmm, we cannot really signal an error here, so let's make
2347  sure to return an invalid fd. */
2348  *((int*) value) = -1;
2349  return;
2350  }
2351 
2352  *((int*) value) = _dbus_dup(real->message->unix_fds[idx.u32], NULL);
2353 #else
2354  *((int*) value) = -1;
2355 #endif
2356  }
2357  else
2358  {
2360  value);
2361  }
2362 }
2363 
2374 int
2376 {
2377  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2378  DBusTypeReader array;
2379  int element_type;
2380  int n_elements = 0;
2381 
2382  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2383  _dbus_return_val_if_fail (_dbus_type_reader_get_current_type (&real->u.reader)
2384  == DBUS_TYPE_ARRAY, 0);
2385 
2386  element_type = _dbus_type_reader_get_element_type (&real->u.reader);
2387  _dbus_type_reader_recurse (&real->u.reader, &array);
2388  if (dbus_type_is_fixed (element_type))
2389  {
2390  int alignment = _dbus_type_get_alignment (element_type);
2391  int total_len = _dbus_type_reader_get_array_length (&array);
2392  n_elements = total_len / alignment;
2393  }
2394  else
2395  {
2397  {
2398  ++n_elements;
2399  _dbus_type_reader_next (&array);
2400  }
2401  }
2402 
2403  return n_elements;
2404 }
2405 
2418 int
2420 {
2421  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2422 
2423  _dbus_return_val_if_fail (_dbus_message_iter_check (real), 0);
2424 
2426 }
2427 
2463 void
2465  void *value,
2466  int *n_elements)
2467 {
2468  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2469 #ifndef DBUS_DISABLE_CHECKS
2470  int subtype = _dbus_type_reader_get_current_type(&real->u.reader);
2471 
2472  _dbus_return_if_fail (_dbus_message_iter_check (real));
2473  _dbus_return_if_fail (value != NULL);
2474  _dbus_return_if_fail ((subtype == DBUS_TYPE_INVALID) ||
2475  (dbus_type_is_fixed (subtype) && subtype != DBUS_TYPE_UNIX_FD));
2476 #endif
2477 
2479  value, n_elements);
2480 }
2481 
2493 void
2495  DBusMessageIter *iter)
2496 {
2497  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2498 
2499  _dbus_return_if_fail (message != NULL);
2500  _dbus_return_if_fail (iter != NULL);
2501 
2502  _dbus_message_iter_init_common (message, real,
2503  DBUS_MESSAGE_ITER_TYPE_WRITER);
2504 
2505  /* We create the signature string and point iterators at it "on demand"
2506  * when a value is actually appended. That means that init() never fails
2507  * due to OOM.
2508  */
2510  _dbus_header_get_byte_order (&message->header),
2511  &message->body,
2512  _dbus_string_get_length (&message->body));
2513 }
2514 
2523 static dbus_bool_t
2524 _dbus_message_iter_open_signature (DBusMessageRealIter *real)
2525 {
2526  DBusString *str;
2527  const DBusString *current_sig;
2528  int current_sig_pos;
2529 
2530  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2531 
2532  if (real->u.writer.type_str != NULL)
2533  {
2534  _dbus_assert (real->sig_refcount > 0);
2535  real->sig_refcount += 1;
2536  return TRUE;
2537  }
2538 
2539  str = dbus_new (DBusString, 1);
2540  if (str == NULL)
2541  return FALSE;
2542 
2545  &current_sig, &current_sig_pos))
2546  current_sig = NULL;
2547 
2548  if (current_sig)
2549  {
2550  int current_len;
2551 
2552  current_len = _dbus_string_get_byte (current_sig, current_sig_pos);
2553  current_sig_pos += 1; /* move on to sig data */
2554 
2555  if (!_dbus_string_init_preallocated (str, current_len + 4))
2556  {
2557  dbus_free (str);
2558  return FALSE;
2559  }
2560 
2561  if (!_dbus_string_copy_len (current_sig, current_sig_pos, current_len,
2562  str, 0))
2563  {
2564  _dbus_string_free (str);
2565  dbus_free (str);
2566  return FALSE;
2567  }
2568  }
2569  else
2570  {
2571  if (!_dbus_string_init_preallocated (str, 4))
2572  {
2573  dbus_free (str);
2574  return FALSE;
2575  }
2576  }
2577 
2578  real->sig_refcount = 1;
2579 
2580  /* If this assertion failed, then str would be neither stored in u.writer
2581  * nor freed by this function, resulting in a memory leak. */
2582  _dbus_assert (real->u.writer.type_str == NULL);
2584  str, _dbus_string_get_length (str));
2585  return TRUE;
2586 }
2587 
2597 static dbus_bool_t
2598 _dbus_message_iter_close_signature (DBusMessageRealIter *real)
2599 {
2600  DBusString *str;
2601  const char *v_STRING;
2602  dbus_bool_t retval;
2603 
2604  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2605  _dbus_assert (real->u.writer.type_str != NULL);
2606  _dbus_assert (real->sig_refcount > 0);
2607 
2608  real->sig_refcount -= 1;
2609 
2610  if (real->sig_refcount > 0)
2611  return TRUE;
2612  _dbus_assert (real->sig_refcount == 0);
2613 
2614  retval = TRUE;
2615 
2616  str = real->u.writer.type_str;
2617 
2618  v_STRING = _dbus_string_get_const_data (str);
2622  &v_STRING))
2623  retval = FALSE;
2624 
2626  _dbus_string_free (str);
2627  dbus_free (str);
2628 
2629  return retval;
2630 }
2631 
2639 static void
2640 _dbus_message_iter_abandon_signature (DBusMessageRealIter *real)
2641 {
2642  DBusString *str;
2643 
2644  _dbus_assert (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
2645  _dbus_assert (real->u.writer.type_str != NULL);
2646  _dbus_assert (real->sig_refcount > 0);
2647 
2648  real->sig_refcount -= 1;
2649 
2650  if (real->sig_refcount > 0)
2651  return;
2652  _dbus_assert (real->sig_refcount == 0);
2653 
2654  str = real->u.writer.type_str;
2655 
2657  _dbus_string_free (str);
2658  dbus_free (str);
2659 }
2660 
2661 #ifndef DBUS_DISABLE_CHECKS
2662 static dbus_bool_t
2663 _dbus_message_iter_append_check (DBusMessageRealIter *iter)
2664 {
2665  if (!_dbus_message_iter_check (iter))
2666  return FALSE;
2667 
2668  if (iter->message->locked)
2669  {
2670  _dbus_warn_check_failed ("dbus append iterator can't be used: message is locked (has already been sent)");
2671  return FALSE;
2672  }
2673 
2674  return TRUE;
2675 }
2676 #endif /* DBUS_DISABLE_CHECKS */
2677 
2678 #ifdef HAVE_UNIX_FD_PASSING
2679 static int *
2680 expand_fd_array(DBusMessage *m,
2681  unsigned n)
2682 {
2683  _dbus_assert(m);
2684 
2685  /* This makes space for adding n new fds to the array and returns a
2686  pointer to the place were the first fd should be put. */
2687 
2688  if (m->n_unix_fds + n > m->n_unix_fds_allocated)
2689  {
2690  unsigned k;
2691  int *p;
2692 
2693  /* Make twice as much space as necessary */
2694  k = (m->n_unix_fds + n) * 2;
2695 
2696  /* Allocate at least four */
2697  if (k < 4)
2698  k = 4;
2699 
2700  p = dbus_realloc(m->unix_fds, k * sizeof(int));
2701  if (p == NULL)
2702  return NULL;
2703 
2704  m->unix_fds = p;
2705  m->n_unix_fds_allocated = k;
2706  }
2707 
2708  return m->unix_fds + m->n_unix_fds;
2709 }
2710 #endif
2711 
2733  int type,
2734  const void *value)
2735 {
2736  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2737  dbus_bool_t ret;
2738 
2739  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2740  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2741  _dbus_return_val_if_fail (dbus_type_is_basic (type), FALSE);
2742  _dbus_return_val_if_fail (value != NULL, FALSE);
2743 
2744 #ifndef DBUS_DISABLE_CHECKS
2745  switch (type)
2746  {
2747  DBusString str;
2748  DBusValidity signature_validity;
2749  const char * const *string_p;
2750  const dbus_bool_t *bool_p;
2751 
2752  case DBUS_TYPE_STRING:
2753  string_p = value;
2754  _dbus_return_val_if_fail (_dbus_check_is_valid_utf8 (*string_p), FALSE);
2755  break;
2756 
2757  case DBUS_TYPE_OBJECT_PATH:
2758  string_p = value;
2759  _dbus_return_val_if_fail (_dbus_check_is_valid_path (*string_p), FALSE);
2760  break;
2761 
2762  case DBUS_TYPE_SIGNATURE:
2763  string_p = value;
2764  _dbus_string_init_const (&str, *string_p);
2765  signature_validity = _dbus_validate_signature_with_reason (&str,
2766  0,
2767  _dbus_string_get_length (&str));
2768 
2769  if (signature_validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
2770  return FALSE;
2771 
2772  _dbus_return_val_if_fail (signature_validity == DBUS_VALID, FALSE);
2773  break;
2774 
2775  case DBUS_TYPE_BOOLEAN:
2776  bool_p = value;
2777  _dbus_return_val_if_fail (*bool_p == 0 || *bool_p == 1, FALSE);
2778  break;
2779 
2780  default:
2781  {
2782  /* nothing to check, all possible values are allowed */
2783  }
2784  }
2785 #endif
2786 
2787  if (!_dbus_message_iter_open_signature (real))
2788  return FALSE;
2789 
2790  if (type == DBUS_TYPE_UNIX_FD)
2791  {
2792 #ifdef HAVE_UNIX_FD_PASSING
2793  int *fds;
2794  dbus_uint32_t u;
2795 
2796  ret = FALSE;
2797 
2798  /* First step, include the fd in the fd list of this message */
2799  if (!(fds = expand_fd_array(real->message, 1)))
2800  goto out;
2801 
2802  *fds = _dbus_dup(*(int*) value, NULL);
2803  if (*fds < 0)
2804  goto out;
2805 
2806  u = real->message->n_unix_fds;
2807 
2808  /* Second step, write the index to the fd */
2809  if (!(ret = _dbus_type_writer_write_basic (&real->u.writer, DBUS_TYPE_UNIX_FD, &u))) {
2810  _dbus_close(*fds, NULL);
2811  goto out;
2812  }
2813 
2814  real->message->n_unix_fds += 1;
2815  u += 1;
2816 
2817  /* Final step, update the header accordingly */
2821  &u);
2822 
2823  /* If any of these operations fail the message is
2824  hosed. However, no memory or fds should be leaked since what
2825  has been added to message has been added to the message, and
2826  can hence be accounted for when the message is being
2827  freed. */
2828 #else
2829  ret = FALSE;
2830  /* This is redundant (we could just fall through), but it avoids
2831  * -Wunused-label in builds that don't HAVE_UNIX_FD_PASSING */
2832  goto out;
2833 #endif
2834  }
2835  else
2836  {
2837  ret = _dbus_type_writer_write_basic (&real->u.writer, type, value);
2838  }
2839 
2840 out:
2841  if (!_dbus_message_iter_close_signature (real))
2842  ret = FALSE;
2843 
2844  return ret;
2845 }
2846 
2884  int element_type,
2885  const void *value,
2886  int n_elements)
2887 {
2888  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2889  dbus_bool_t ret;
2890 
2891  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2892  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2893  _dbus_return_val_if_fail (dbus_type_is_fixed (element_type) && element_type != DBUS_TYPE_UNIX_FD, FALSE);
2894  _dbus_return_val_if_fail (real->u.writer.container_type == DBUS_TYPE_ARRAY, FALSE);
2895  _dbus_return_val_if_fail (value != NULL, FALSE);
2896  _dbus_return_val_if_fail (n_elements >= 0, FALSE);
2897  _dbus_return_val_if_fail (n_elements <=
2899  FALSE);
2900 
2901 #ifndef DBUS_DISABLE_CHECKS
2902  if (element_type == DBUS_TYPE_BOOLEAN)
2903  {
2904  const dbus_bool_t * const *bools = value;
2905  int i;
2906 
2907  for (i = 0; i < n_elements; i++)
2908  {
2909  _dbus_return_val_if_fail ((*bools)[i] == 0 || (*bools)[i] == 1, FALSE);
2910  }
2911  }
2912 #endif
2913 
2914  ret = _dbus_type_writer_write_fixed_multi (&real->u.writer, element_type, value, n_elements);
2915 
2916  return ret;
2917 }
2918 
2948  int type,
2949  const char *contained_signature,
2950  DBusMessageIter *sub)
2951 {
2952  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
2953  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
2954  DBusString contained_str;
2955  DBusValidity contained_signature_validity;
2956  dbus_bool_t ret;
2957 
2958  _dbus_return_val_if_fail (sub != NULL, FALSE);
2959  /* Do our best to make sure the sub-iterator doesn't contain something
2960  * valid-looking on failure */
2961  _dbus_message_real_iter_zero (real_sub);
2962 
2963  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
2964  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
2965  _dbus_return_val_if_fail (dbus_type_is_container (type), FALSE);
2966  _dbus_return_val_if_fail ((type == DBUS_TYPE_STRUCT &&
2967  contained_signature == NULL) ||
2968  (type == DBUS_TYPE_DICT_ENTRY &&
2969  contained_signature == NULL) ||
2970  (type == DBUS_TYPE_VARIANT &&
2971  contained_signature != NULL) ||
2972  (type == DBUS_TYPE_ARRAY &&
2973  contained_signature != NULL), FALSE);
2974 
2975  /* this would fail if the contained_signature is a dict entry, since
2976  * dict entries are invalid signatures standalone (they must be in
2977  * an array)
2978  */
2979  if (contained_signature != NULL)
2980  {
2981  _dbus_string_init_const (&contained_str, contained_signature);
2982  contained_signature_validity = _dbus_validate_signature_with_reason (&contained_str,
2983  0,
2984  _dbus_string_get_length (&contained_str));
2985 
2986  if (contained_signature_validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
2987  return FALSE;
2988  }
2989  else
2990  {
2991  /* just some placeholder value */
2992  contained_signature_validity = DBUS_VALID_BUT_INCOMPLETE;
2993  }
2994 
2995  _dbus_return_val_if_fail ((type == DBUS_TYPE_ARRAY && contained_signature && *contained_signature == DBUS_DICT_ENTRY_BEGIN_CHAR) ||
2996  contained_signature == NULL ||
2997  contained_signature_validity == DBUS_VALID,
2998  FALSE);
2999 
3000  if (!_dbus_message_iter_open_signature (real))
3001  return FALSE;
3002 
3003  ret = FALSE;
3004  *real_sub = *real;
3005 
3006  if (contained_signature != NULL)
3007  {
3008  _dbus_string_init_const (&contained_str, contained_signature);
3009 
3010  ret = _dbus_type_writer_recurse (&real->u.writer,
3011  type,
3012  &contained_str, 0,
3013  &real_sub->u.writer);
3014  }
3015  else
3016  {
3017  ret = _dbus_type_writer_recurse (&real->u.writer,
3018  type,
3019  NULL, 0,
3020  &real_sub->u.writer);
3021  }
3022 
3023  if (!ret)
3024  _dbus_message_iter_abandon_signature (real);
3025 
3026  return ret;
3027 }
3028 
3029 
3051  DBusMessageIter *sub)
3052 {
3053  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3054  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3055  dbus_bool_t ret;
3056 
3057  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real), FALSE);
3058  _dbus_return_val_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3059  _dbus_return_val_if_fail (_dbus_message_iter_append_check (real_sub), FALSE);
3060  _dbus_return_val_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER, FALSE);
3061 
3062  ret = _dbus_type_writer_unrecurse (&real->u.writer,
3063  &real_sub->u.writer);
3064  _dbus_message_real_iter_zero (real_sub);
3065 
3066  if (!_dbus_message_iter_close_signature (real))
3067  ret = FALSE;
3068 
3069  return ret;
3070 }
3071 
3083 void
3085  DBusMessageIter *sub)
3086 {
3087  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3088  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3089 
3090 #ifndef DBUS_DISABLE_CHECKS
3091  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3092  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3093  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3094  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3095 #endif
3096 
3097  _dbus_message_iter_abandon_signature (real);
3098  _dbus_message_real_iter_zero (real_sub);
3099 }
3100 
3142 void
3144  DBusMessageIter *sub)
3145 {
3146  DBusMessageRealIter *real = (DBusMessageRealIter *)iter;
3147  DBusMessageRealIter *real_sub = (DBusMessageRealIter *)sub;
3148 
3149  /* If both the parent and the child are zeroed out, then either we didn't
3150  * even get as far as successfully recursing into the parent, or we already
3151  * closed both the child and the parent. For example, in the code sample
3152  * in the doc-comment above, this happens for
3153  * abandon_container_if_open (&outer, &inner) if the first open_container
3154  * call failed, or if we reached result = TRUE and fell through. */
3155  if (_dbus_message_real_iter_is_zeroed (real) &&
3156  _dbus_message_real_iter_is_zeroed (real_sub))
3157  return;
3158 
3159 #ifndef DBUS_DISABLE_CHECKS
3160  /* If the child is not zeroed out, but the parent is, then something has
3161  * gone horribly wrong (in practice that would probably mean both are
3162  * uninitialized or corrupt, and the parent happens to have ended up
3163  * all-bytes-zero). */
3164  _dbus_return_if_fail (_dbus_message_iter_append_check (real));
3165  _dbus_return_if_fail (real->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3166 #endif
3167 
3168  /* If the parent is not zeroed out, but the child is, then either we did
3169  * not successfully open the child, or we already closed the child. This
3170  * means we do not own a reference to the parent's signature, so it would
3171  * be wrong to release it; so we must not call abandon_signature() here.
3172  * In the code sample in the doc-comment above, this happens for
3173  * abandon_container_if_open (&outer, &inner) if the second open_container
3174  * call failed, or if the second close_container call failed. */
3175  if (_dbus_message_real_iter_is_zeroed (real_sub))
3176  return;
3177 
3178 #ifndef DBUS_DISABLE_CHECKS
3179  _dbus_return_if_fail (_dbus_message_iter_append_check (real_sub));
3180  _dbus_return_if_fail (real_sub->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
3181 #endif
3182 
3183  /* If neither the parent nor the child is zeroed out, then we genuinely
3184  * have an open container; close it. In the code sample in the doc-comment,
3185  * this happens for abandon_container_if_open (&outer, &inner) if the
3186  * append_basic call failed. */
3187  _dbus_message_iter_abandon_signature (real);
3188  _dbus_message_real_iter_zero (real_sub);
3189 }
3190 
3207 void
3209  dbus_bool_t no_reply)
3210 {
3211  _dbus_return_if_fail (message != NULL);
3212  _dbus_return_if_fail (!message->locked);
3213 
3214  _dbus_header_toggle_flag (&message->header,
3216  no_reply);
3217 }
3218 
3228 {
3229  _dbus_return_val_if_fail (message != NULL, FALSE);
3230 
3231  return _dbus_header_get_flag (&message->header,
3233 }
3234 
3249 void
3251  dbus_bool_t auto_start)
3252 {
3253  _dbus_return_if_fail (message != NULL);
3254  _dbus_return_if_fail (!message->locked);
3255 
3256  _dbus_header_toggle_flag (&message->header,
3258  !auto_start);
3259 }
3260 
3270 {
3271  _dbus_return_val_if_fail (message != NULL, FALSE);
3272 
3273  return !_dbus_header_get_flag (&message->header,
3275 }
3276 
3277 
3292  const char *object_path)
3293 {
3294  _dbus_return_val_if_fail (message != NULL, FALSE);
3295  _dbus_return_val_if_fail (!message->locked, FALSE);
3296  _dbus_return_val_if_fail (object_path == NULL ||
3297  _dbus_check_is_valid_path (object_path),
3298  FALSE);
3299 
3300  return set_or_delete_string_field (message,
3303  object_path);
3304 }
3305 
3319 const char*
3321 {
3322  const char *v;
3323 
3324  _dbus_return_val_if_fail (message != NULL, NULL);
3325 
3326  v = NULL; /* in case field doesn't exist */
3330  (void *) &v);
3331  return v;
3332 }
3333 
3345  const char *path)
3346 {
3347  const char *msg_path;
3348  msg_path = dbus_message_get_path (message);
3349 
3350  if (msg_path == NULL)
3351  {
3352  if (path == NULL)
3353  return TRUE;
3354  else
3355  return FALSE;
3356  }
3357 
3358  if (path == NULL)
3359  return FALSE;
3360 
3361  if (strcmp (msg_path, path) == 0)
3362  return TRUE;
3363 
3364  return FALSE;
3365 }
3366 
3389  char ***path)
3390 {
3391  const char *v;
3392 
3393  _dbus_return_val_if_fail (message != NULL, FALSE);
3394  _dbus_return_val_if_fail (path != NULL, FALSE);
3395 
3396  *path = NULL;
3397 
3398  v = dbus_message_get_path (message);
3399  if (v != NULL)
3400  {
3401  if (!_dbus_decompose_path (v, strlen (v),
3402  path, NULL))
3403  return FALSE;
3404  }
3405  return TRUE;
3406 }
3407 
3423  const char *iface)
3424 {
3425  _dbus_return_val_if_fail (message != NULL, FALSE);
3426  _dbus_return_val_if_fail (!message->locked, FALSE);
3427  _dbus_return_val_if_fail (iface == NULL ||
3428  _dbus_check_is_valid_interface (iface),
3429  FALSE);
3430 
3431  return set_or_delete_string_field (message,
3434  iface);
3435 }
3436 
3450 const char*
3452 {
3453  const char *v;
3454 
3455  _dbus_return_val_if_fail (message != NULL, NULL);
3456 
3457  v = NULL; /* in case field doesn't exist */
3461  (void *) &v);
3462  return v;
3463 }
3464 
3474  const char *iface)
3475 {
3476  const char *msg_interface;
3477  msg_interface = dbus_message_get_interface (message);
3478 
3479  if (msg_interface == NULL)
3480  {
3481  if (iface == NULL)
3482  return TRUE;
3483  else
3484  return FALSE;
3485  }
3486 
3487  if (iface == NULL)
3488  return FALSE;
3489 
3490  if (strcmp (msg_interface, iface) == 0)
3491  return TRUE;
3492 
3493  return FALSE;
3494 
3495 }
3496 
3511  const char *member)
3512 {
3513  _dbus_return_val_if_fail (message != NULL, FALSE);
3514  _dbus_return_val_if_fail (!message->locked, FALSE);
3515  _dbus_return_val_if_fail (member == NULL ||
3516  _dbus_check_is_valid_member (member),
3517  FALSE);
3518 
3519  return set_or_delete_string_field (message,
3522  member);
3523 }
3524 
3536 const char*
3538 {
3539  const char *v;
3540 
3541  _dbus_return_val_if_fail (message != NULL, NULL);
3542 
3543  v = NULL; /* in case field doesn't exist */
3547  (void *) &v);
3548  return v;
3549 }
3550 
3560  const char *member)
3561 {
3562  const char *msg_member;
3563  msg_member = dbus_message_get_member (message);
3564 
3565  if (msg_member == NULL)
3566  {
3567  if (member == NULL)
3568  return TRUE;
3569  else
3570  return FALSE;
3571  }
3572 
3573  if (member == NULL)
3574  return FALSE;
3575 
3576  if (strcmp (msg_member, member) == 0)
3577  return TRUE;
3578 
3579  return FALSE;
3580 
3581 }
3582 
3596  const char *error_name)
3597 {
3598  _dbus_return_val_if_fail (message != NULL, FALSE);
3599  _dbus_return_val_if_fail (!message->locked, FALSE);
3600  _dbus_return_val_if_fail (error_name == NULL ||
3601  _dbus_check_is_valid_error_name (error_name),
3602  FALSE);
3603 
3604  return set_or_delete_string_field (message,
3607  error_name);
3608 }
3609 
3620 const char*
3622 {
3623  const char *v;
3624 
3625  _dbus_return_val_if_fail (message != NULL, NULL);
3626 
3627  v = NULL; /* in case field doesn't exist */
3631  (void *) &v);
3632  return v;
3633 }
3634 
3650  const char *destination)
3651 {
3652  _dbus_return_val_if_fail (message != NULL, FALSE);
3653  _dbus_return_val_if_fail (!message->locked, FALSE);
3654  _dbus_return_val_if_fail (destination == NULL ||
3655  _dbus_check_is_valid_bus_name (destination),
3656  FALSE);
3657 
3658  return set_or_delete_string_field (message,
3661  destination);
3662 }
3663 
3673 const char*
3675 {
3676  const char *v;
3677 
3678  _dbus_return_val_if_fail (message != NULL, NULL);
3679 
3680  v = NULL; /* in case field doesn't exist */
3684  (void *) &v);
3685  return v;
3686 }
3687 
3704  const char *sender)
3705 {
3706  _dbus_return_val_if_fail (message != NULL, FALSE);
3707  _dbus_return_val_if_fail (!message->locked, FALSE);
3708  _dbus_return_val_if_fail (sender == NULL ||
3709  _dbus_check_is_valid_bus_name (sender),
3710  FALSE);
3711 
3712  return set_or_delete_string_field (message,
3715  sender);
3716 }
3717 
3733 const char*
3735 {
3736  const char *v;
3737 
3738  _dbus_return_val_if_fail (message != NULL, NULL);
3739 
3740  v = NULL; /* in case field doesn't exist */
3744  (void *) &v);
3745  return v;
3746 }
3747 
3766 const char*
3768 {
3769  const DBusString *type_str;
3770  int type_pos;
3771 
3772  _dbus_return_val_if_fail (message != NULL, NULL);
3773 
3774  get_const_signature (&message->header, &type_str, &type_pos);
3775 
3776  return _dbus_string_get_const_data_len (type_str, type_pos, 0);
3777 }
3778 
3779 static dbus_bool_t
3780 _dbus_message_has_type_interface_member (DBusMessage *message,
3781  int type,
3782  const char *iface,
3783  const char *member)
3784 {
3785  const char *n;
3786 
3787  _dbus_assert (message != NULL);
3788  _dbus_assert (iface != NULL);
3789  _dbus_assert (member != NULL);
3790 
3791  if (dbus_message_get_type (message) != type)
3792  return FALSE;
3793 
3794  /* Optimize by checking the short member name first
3795  * instead of the longer interface name
3796  */
3797 
3798  n = dbus_message_get_member (message);
3799 
3800  if (n && strcmp (n, member) == 0)
3801  {
3802  n = dbus_message_get_interface (message);
3803 
3804  if (n == NULL || strcmp (n, iface) == 0)
3805  return TRUE;
3806  }
3807 
3808  return FALSE;
3809 }
3810 
3827  const char *iface,
3828  const char *method)
3829 {
3830  _dbus_return_val_if_fail (message != NULL, FALSE);
3831  _dbus_return_val_if_fail (iface != NULL, FALSE);
3832  _dbus_return_val_if_fail (method != NULL, FALSE);
3833  /* don't check that interface/method are valid since it would be
3834  * expensive, and not catch many common errors
3835  */
3836 
3837  return _dbus_message_has_type_interface_member (message,
3839  iface, method);
3840 }
3841 
3855  const char *iface,
3856  const char *signal_name)
3857 {
3858  _dbus_return_val_if_fail (message != NULL, FALSE);
3859  _dbus_return_val_if_fail (iface != NULL, FALSE);
3860  _dbus_return_val_if_fail (signal_name != NULL, FALSE);
3861  /* don't check that interface/name are valid since it would be
3862  * expensive, and not catch many common errors
3863  */
3864 
3865  return _dbus_message_has_type_interface_member (message,
3867  iface, signal_name);
3868 }
3869 
3882  const char *error_name)
3883 {
3884  const char *n;
3885 
3886  _dbus_return_val_if_fail (message != NULL, FALSE);
3887  _dbus_return_val_if_fail (error_name != NULL, FALSE);
3888  /* don't check that error_name is valid since it would be expensive,
3889  * and not catch many common errors
3890  */
3891 
3893  return FALSE;
3894 
3895  n = dbus_message_get_error_name (message);
3896 
3897  if (n && strcmp (n, error_name) == 0)
3898  return TRUE;
3899  else
3900  return FALSE;
3901 }
3902 
3915  const char *name)
3916 {
3917  const char *s;
3918 
3919  _dbus_return_val_if_fail (message != NULL, FALSE);
3920  _dbus_return_val_if_fail (name != NULL, FALSE);
3921  /* don't check that name is valid since it would be expensive, and
3922  * not catch many common errors
3923  */
3924 
3925  s = dbus_message_get_destination (message);
3926 
3927  if (s && strcmp (s, name) == 0)
3928  return TRUE;
3929  else
3930  return FALSE;
3931 }
3932 
3950  const char *name)
3951 {
3952  const char *s;
3953 
3954  _dbus_return_val_if_fail (message != NULL, FALSE);
3955  _dbus_return_val_if_fail (name != NULL, FALSE);
3956  /* don't check that name is valid since it would be expensive, and
3957  * not catch many common errors
3958  */
3959 
3960  s = dbus_message_get_sender (message);
3961 
3962  if (s && strcmp (s, name) == 0)
3963  return TRUE;
3964  else
3965  return FALSE;
3966 }
3967 
3979  const char *signature)
3980 {
3981  const char *s;
3982 
3983  _dbus_return_val_if_fail (message != NULL, FALSE);
3984  _dbus_return_val_if_fail (signature != NULL, FALSE);
3985  /* don't check that signature is valid since it would be expensive,
3986  * and not catch many common errors
3987  */
3988 
3989  s = dbus_message_get_signature (message);
3990 
3991  if (s && strcmp (s, signature) == 0)
3992  return TRUE;
3993  else
3994  return FALSE;
3995 }
3996 
4021  DBusMessage *message)
4022 {
4023  const char *str;
4024 
4025  _dbus_return_val_if_fail (message != NULL, FALSE);
4026  _dbus_return_val_if_error_is_set (error, FALSE);
4027 
4029  return FALSE;
4030 
4031  str = NULL;
4032  dbus_message_get_args (message, NULL,
4033  DBUS_TYPE_STRING, &str,
4035 
4036  dbus_set_error (error, dbus_message_get_error_name (message),
4037  str ? "%s" : NULL, str);
4038 
4039  return TRUE;
4040 }
4041 
4050 {
4051 #ifdef HAVE_UNIX_FD_PASSING
4052  _dbus_assert(message);
4053 
4054  return message->n_unix_fds > 0;
4055 #else
4056  return FALSE;
4057 #endif
4058 }
4059 
4078 #define INITIAL_LOADER_DATA_LEN 32
4079 
4088 {
4089  DBusMessageLoader *loader;
4090 
4091  loader = dbus_new0 (DBusMessageLoader, 1);
4092  if (loader == NULL)
4093  return NULL;
4094 
4095  loader->refcount = 1;
4096 
4097  loader->corrupted = FALSE;
4098  loader->corruption_reason = DBUS_VALID;
4099 
4100  /* this can be configured by the app, but defaults to the protocol max */
4102 
4103  /* We set a very relatively conservative default here since due to how
4104  SCM_RIGHTS works we need to preallocate an fd array of the maximum
4105  number of unix fds we want to receive in advance. A
4106  try-and-reallocate loop is not possible. */
4107  loader->max_message_unix_fds = DBUS_DEFAULT_MESSAGE_UNIX_FDS;
4108 
4109  if (!_dbus_string_init (&loader->data))
4110  {
4111  dbus_free (loader);
4112  return NULL;
4113  }
4114 
4115  /* preallocate the buffer for speed, ignore failure */
4117  _dbus_string_set_length (&loader->data, 0);
4118 
4119 #ifdef HAVE_UNIX_FD_PASSING
4120  loader->unix_fds = NULL;
4121  loader->n_unix_fds = loader->n_unix_fds_allocated = 0;
4122  loader->unix_fds_outstanding = FALSE;
4123 #endif
4124 
4125  return loader;
4126 }
4127 
4136 {
4137  loader->refcount += 1;
4138 
4139  return loader;
4140 }
4141 
4148 void
4150 {
4151  loader->refcount -= 1;
4152  if (loader->refcount == 0)
4153  {
4154 #ifdef HAVE_UNIX_FD_PASSING
4155  close_unix_fds(loader->unix_fds, &loader->n_unix_fds);
4156  dbus_free(loader->unix_fds);
4157 #endif
4158  _dbus_list_foreach (&loader->messages,
4160  NULL);
4161  _dbus_list_clear (&loader->messages);
4162  _dbus_string_free (&loader->data);
4163  dbus_free (loader);
4164  }
4165 }
4166 
4185 void
4187  DBusString **buffer,
4188  int *max_to_read,
4189  dbus_bool_t *may_read_fds)
4190 {
4191  _dbus_assert (!loader->buffer_outstanding);
4192 
4193  *buffer = &loader->data;
4194 
4195  loader->buffer_outstanding = TRUE;
4196 
4197  if (max_to_read != NULL)
4198  {
4199 #ifdef HAVE_UNIX_FD_PASSING
4200  int offset = 0;
4201  int remain;
4202  int byte_order;
4203  int fields_array_len;
4204  int header_len;
4205  int body_len;
4206 #endif
4207 
4208  *max_to_read = DBUS_MAXIMUM_MESSAGE_LENGTH;
4209  *may_read_fds = TRUE;
4210 
4211 #ifdef HAVE_UNIX_FD_PASSING
4212  /* If we aren't holding onto any fds, we can read as much as we want
4213  * (fast path). */
4214  if (loader->n_unix_fds == 0)
4215  return;
4216 
4217  /* Slow path: we have a message with some fds in it. We don't want
4218  * to start on the next message until this one is out of the way;
4219  * otherwise a legitimate sender can keep us processing messages
4220  * containing fds, until we disconnect it for having had fds pending
4221  * for too long, a limit that is in place to stop malicious senders
4222  * from setting up recursive fd-passing that takes up our quota and
4223  * will never go away. */
4224 
4225  remain = _dbus_string_get_length (&loader->data);
4226 
4227  while (remain > 0)
4228  {
4229  DBusValidity validity = DBUS_VALIDITY_UNKNOWN;
4230  int needed;
4231 
4232  /* If 0 < remain < DBUS_MINIMUM_HEADER_SIZE, then we've had at
4233  * least the first byte of a message, but we don't know how
4234  * much more to read. Only read the rest of the
4235  * DBUS_MINIMUM_HEADER_SIZE for now; then we'll know. */
4236  if (remain < DBUS_MINIMUM_HEADER_SIZE)
4237  {
4238  *max_to_read = DBUS_MINIMUM_HEADER_SIZE - remain;
4239  *may_read_fds = FALSE;
4240  return;
4241  }
4242 
4244  &validity,
4245  &byte_order,
4246  &fields_array_len,
4247  &header_len,
4248  &body_len,
4249  &loader->data,
4250  offset,
4251  remain))
4252  {
4253  /* If a message in the buffer is invalid, we're going to
4254  * disconnect the sender anyway, so reading an arbitrary amount
4255  * is fine. */
4256  if (validity != DBUS_VALID)
4257  return;
4258 
4259  /* We have a partial message, with the
4260  * DBUS_MINIMUM_HEADER_SIZE-byte fixed part of the header (which
4261  * lets us work out how much more we need), but no more. Read
4262  * the rest of the message. */
4263  needed = header_len + body_len;
4264  _dbus_assert (needed > remain);
4265  *max_to_read = needed - remain;
4266  *may_read_fds = FALSE;
4267  return;
4268  }
4269 
4270  /* Skip over entire messages until we have less than a message
4271  * remaining. */
4272  needed = header_len + body_len;
4274  _dbus_assert (remain >= needed);
4275  remain -= needed;
4276  offset += needed;
4277  }
4278 #endif
4279  }
4280 }
4281 
4291 void
4293  DBusString *buffer)
4294 {
4295  _dbus_assert (loader->buffer_outstanding);
4296  _dbus_assert (buffer == &loader->data);
4297 
4298  loader->buffer_outstanding = FALSE;
4299 }
4300 
4301 #ifdef HAVE_UNIX_FD_PASSING
4302 
4313 _dbus_message_loader_get_unix_fds(DBusMessageLoader *loader,
4314  int **fds,
4315  unsigned *max_n_fds)
4316 {
4317  _dbus_assert (!loader->unix_fds_outstanding);
4318 
4319  /* Allocate space where we can put the fds we read. We allocate
4320  space for max_message_unix_fds since this is an
4321  upper limit how many fds can be received within a single
4322  message. Since SCM_RIGHTS doesn't allow a reallocate+retry logic
4323  we are allocating the maximum possible array size right from the
4324  beginning. This sucks a bit, however unless SCM_RIGHTS is fixed
4325  there is no better way. */
4326 
4327  if (loader->n_unix_fds_allocated < loader->max_message_unix_fds)
4328  {
4329  int *a = dbus_realloc(loader->unix_fds,
4330  loader->max_message_unix_fds * sizeof(loader->unix_fds[0]));
4331 
4332  if (!a)
4333  return FALSE;
4334 
4335  loader->unix_fds = a;
4336  loader->n_unix_fds_allocated = loader->max_message_unix_fds;
4337  }
4338 
4339  *fds = loader->unix_fds + loader->n_unix_fds;
4340  *max_n_fds = loader->n_unix_fds_allocated - loader->n_unix_fds;
4341 
4342  loader->unix_fds_outstanding = TRUE;
4343  return TRUE;
4344 }
4345 
4356 void
4357 _dbus_message_loader_return_unix_fds(DBusMessageLoader *loader,
4358  int *fds,
4359  unsigned n_fds)
4360 {
4361  _dbus_assert(loader->unix_fds_outstanding);
4362  _dbus_assert(loader->unix_fds + loader->n_unix_fds == fds);
4363  _dbus_assert(loader->n_unix_fds + n_fds <= loader->n_unix_fds_allocated);
4364 
4365  loader->n_unix_fds += n_fds;
4366  loader->unix_fds_outstanding = FALSE;
4367 
4368  if (n_fds && loader->unix_fds_change)
4369  loader->unix_fds_change (loader->unix_fds_change_data);
4370 }
4371 #endif
4372 
4373 /*
4374  * FIXME when we move the header out of the buffer, that memmoves all
4375  * buffered messages. Kind of crappy.
4376  *
4377  * Also we copy the header and body, which is kind of crappy. To
4378  * avoid this, we have to allow header and body to be in a single
4379  * memory block, which is good for messages we read and bad for
4380  * messages we are creating. But we could move_len() the buffer into
4381  * this single memory block, and move_len() will just swap the buffers
4382  * if you're moving the entire buffer replacing the dest string.
4383  *
4384  * We could also have the message loader tell the transport how many
4385  * bytes to read; so it would first ask for some arbitrary number like
4386  * 256, then if the message was incomplete it would use the
4387  * header/body len to ask for exactly the size of the message (or
4388  * blocks the size of a typical kernel buffer for the socket). That
4389  * way we don't get trailing bytes in the buffer that have to be
4390  * memmoved. Though I suppose we also don't have a chance of reading a
4391  * bunch of small messages at once, so the optimization may be stupid.
4392  *
4393  * Another approach would be to keep a "start" index into
4394  * loader->data and only delete it occasionally, instead of after
4395  * each message is loaded.
4396  *
4397  * load_message() returns FALSE if not enough memory OR the loader was corrupted
4398  */
4399 static dbus_bool_t
4400 load_message (DBusMessageLoader *loader,
4401  DBusMessage *message,
4402  int byte_order,
4403  int fields_array_len,
4404  int header_len,
4405  int body_len)
4406 {
4407  dbus_bool_t oom;
4408  DBusValidity validity;
4409  const DBusString *type_str;
4410  int type_pos;
4411  DBusValidationMode mode;
4412  dbus_uint32_t n_unix_fds = 0;
4413 
4414  mode = DBUS_VALIDATION_MODE_DATA_IS_UNTRUSTED;
4415 
4416  oom = FALSE;
4417 
4418 #if 0
4419  _dbus_verbose_bytes_of_string (&loader->data, 0, header_len /* + body_len */);
4420 #endif
4421 
4422  /* 1. VALIDATE AND COPY OVER HEADER */
4423  _dbus_assert (_dbus_string_get_length (&message->header.data) == 0);
4424  _dbus_assert ((header_len + body_len) <= _dbus_string_get_length (&loader->data));
4425 
4426  if (!_dbus_header_load (&message->header,
4427  mode,
4428  &validity,
4429  byte_order,
4430  fields_array_len,
4431  header_len,
4432  body_len,
4433  &loader->data, 0,
4434  _dbus_string_get_length (&loader->data)))
4435  {
4436  _dbus_verbose ("Failed to load header for new message code %d\n", validity);
4437 
4438  /* assert here so we can catch any code that still uses DBUS_VALID to indicate
4439  oom errors. They should use DBUS_VALIDITY_UNKNOWN_OOM_ERROR instead */
4440  _dbus_assert (validity != DBUS_VALID);
4441 
4442  if (validity == DBUS_VALIDITY_UNKNOWN_OOM_ERROR)
4443  oom = TRUE;
4444  else
4445  {
4446  loader->corrupted = TRUE;
4447  loader->corruption_reason = validity;
4448  }
4449  goto failed;
4450  }
4451 
4452  _dbus_assert (validity == DBUS_VALID);
4453 
4454  /* 2. VALIDATE BODY */
4455  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
4456  {
4457  get_const_signature (&message->header, &type_str, &type_pos);
4458 
4459  /* Because the bytes_remaining arg is NULL, this validates that the
4460  * body is the right length
4461  */
4462  validity = _dbus_validate_body_with_reason (type_str,
4463  type_pos,
4464  byte_order,
4465  NULL,
4466  &loader->data,
4467  header_len,
4468  body_len);
4469  if (validity != DBUS_VALID)
4470  {
4471  _dbus_verbose ("Failed to validate message body code %d\n", validity);
4472 
4473  loader->corrupted = TRUE;
4474  loader->corruption_reason = validity;
4475 
4476  goto failed;
4477  }
4478  }
4479 
4480  /* 3. COPY OVER UNIX FDS */
4484  &n_unix_fds);
4485 
4486 #ifdef HAVE_UNIX_FD_PASSING
4487 
4488  if (n_unix_fds > loader->n_unix_fds)
4489  {
4490  _dbus_verbose("Message contains references to more unix fds than were sent %u != %u\n",
4491  n_unix_fds, loader->n_unix_fds);
4492 
4493  loader->corrupted = TRUE;
4494  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4495  goto failed;
4496  }
4497 
4498  /* If this was a recycled message there might still be
4499  some memory allocated for the fds */
4500  dbus_free(message->unix_fds);
4501 
4502  if (n_unix_fds > 0)
4503  {
4504  message->unix_fds = _dbus_memdup(loader->unix_fds, n_unix_fds * sizeof(message->unix_fds[0]));
4505  if (message->unix_fds == NULL)
4506  {
4507  _dbus_verbose ("Failed to allocate file descriptor array\n");
4508  oom = TRUE;
4509  goto failed;
4510  }
4511 
4512  message->n_unix_fds_allocated = message->n_unix_fds = n_unix_fds;
4513  loader->n_unix_fds -= n_unix_fds;
4514  memmove (loader->unix_fds, loader->unix_fds + n_unix_fds, loader->n_unix_fds * sizeof (loader->unix_fds[0]));
4515 
4516  if (loader->unix_fds_change)
4517  loader->unix_fds_change (loader->unix_fds_change_data);
4518  }
4519  else
4520  message->unix_fds = NULL;
4521 
4522 #else
4523 
4524  if (n_unix_fds > 0)
4525  {
4526  _dbus_verbose ("Hmm, message claims to come with file descriptors "
4527  "but that's not supported on our platform, disconnecting.\n");
4528 
4529  loader->corrupted = TRUE;
4530  loader->corruption_reason = DBUS_INVALID_MISSING_UNIX_FDS;
4531  goto failed;
4532  }
4533 
4534 #endif
4535 
4536  /* 3. COPY OVER BODY AND QUEUE MESSAGE */
4537 
4538  if (!_dbus_list_append (&loader->messages, message))
4539  {
4540  _dbus_verbose ("Failed to append new message to loader queue\n");
4541  oom = TRUE;
4542  goto failed;
4543  }
4544 
4545  _dbus_assert (_dbus_string_get_length (&message->body) == 0);
4547  (header_len + body_len));
4548 
4549  if (!_dbus_string_copy_len (&loader->data, header_len, body_len, &message->body, 0))
4550  {
4551  _dbus_verbose ("Failed to move body into new message\n");
4552  oom = TRUE;
4553  goto failed;
4554  }
4555 
4556  _dbus_string_delete (&loader->data, 0, header_len + body_len);
4557 
4558  /* don't waste more than 2k of memory */
4559  _dbus_string_compact (&loader->data, 2048);
4560 
4561  _dbus_assert (_dbus_string_get_length (&message->header.data) == header_len);
4562  _dbus_assert (_dbus_string_get_length (&message->body) == body_len);
4563 
4564  _dbus_verbose ("Loaded message %p\n", message);
4565 
4566  _dbus_assert (!oom);
4567  _dbus_assert (!loader->corrupted);
4568  _dbus_assert (loader->messages != NULL);
4569  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4570 
4571  return TRUE;
4572 
4573  failed:
4574 
4575  /* Clean up */
4576 
4577  /* does nothing if the message isn't in the list */
4578  _dbus_list_remove_last (&loader->messages, message);
4579 
4580  if (oom)
4581  _dbus_assert (!loader->corrupted);
4582  else
4583  _dbus_assert (loader->corrupted);
4584 
4586 
4587  return FALSE;
4588 }
4589 
4606 {
4607  while (!loader->corrupted &&
4609  {
4610  DBusValidity validity;
4611  int byte_order, fields_array_len, header_len, body_len;
4612 
4614  &validity,
4615  &byte_order,
4616  &fields_array_len,
4617  &header_len,
4618  &body_len,
4619  &loader->data, 0,
4620  _dbus_string_get_length (&loader->data)))
4621  {
4622  DBusMessage *message;
4623 
4624  _dbus_assert (validity == DBUS_VALID);
4625 
4626  message = dbus_message_new_empty_header ();
4627  if (message == NULL)
4628  return FALSE;
4629 
4630  if (!load_message (loader, message,
4631  byte_order, fields_array_len,
4632  header_len, body_len))
4633  {
4634  dbus_message_unref (message);
4635  /* load_message() returns false if corrupted or OOM; if
4636  * corrupted then return TRUE for not OOM
4637  */
4638  return loader->corrupted;
4639  }
4640 
4641  _dbus_assert (loader->messages != NULL);
4642  _dbus_assert (_dbus_list_find_last (&loader->messages, message) != NULL);
4643  }
4644  else
4645  {
4646  _dbus_verbose ("Initial peek at header says we don't have a whole message yet, or data broken with invalid code %d\n",
4647  validity);
4648  if (validity != DBUS_VALID)
4649  {
4650  loader->corrupted = TRUE;
4651  loader->corruption_reason = validity;
4652  }
4653  return TRUE;
4654  }
4655  }
4656 
4657  return TRUE;
4658 }
4659 
4667 DBusMessage*
4669 {
4670  if (loader->messages)
4671  return loader->messages->data;
4672  else
4673  return NULL;
4674 }
4675 
4684 DBusMessage*
4686 {
4687  return _dbus_list_pop_first (&loader->messages);
4688 }
4689 
4698 DBusList*
4700 {
4701  return _dbus_list_pop_first_link (&loader->messages);
4702 }
4703 
4710 void
4712  DBusList *link)
4713 {
4714  _dbus_list_prepend_link (&loader->messages, link);
4715 }
4716 
4728 {
4729  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4730  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4731  return loader->corrupted;
4732 }
4733 
4742 {
4743  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
4744  (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
4745 
4746  return loader->corruption_reason;
4747 }
4748 
4755 void
4757  long size)
4758 {
4759  if (size > DBUS_MAXIMUM_MESSAGE_LENGTH)
4760  {
4761  _dbus_verbose ("clamping requested max message size %ld to %d\n",
4764  }
4765  loader->max_message_size = size;
4766 }
4767 
4774 long
4776 {
4777  return loader->max_message_size;
4778 }
4779 
4786 void
4788  long n)
4789 {
4791  {
4792  _dbus_verbose ("clamping requested max message unix_fds %ld to %d\n",
4795  }
4796  loader->max_message_unix_fds = n;
4797 }
4798 
4805 long
4807 {
4808  return loader->max_message_unix_fds;
4809 }
4810 
4816 int
4818 {
4819 #ifdef HAVE_UNIX_FD_PASSING
4820  return loader->n_unix_fds;
4821 #else
4822  return 0;
4823 #endif
4824 }
4825 
4834 void
4836  void (* callback) (void *),
4837  void *data)
4838 {
4839 #ifdef HAVE_UNIX_FD_PASSING
4840  loader->unix_fds_change = callback;
4841  loader->unix_fds_change_data = data;
4842 #endif
4843 }
4844 
4845 static DBusDataSlotAllocator slot_allocator =
4846  _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots));
4847 
4864 {
4865  return _dbus_data_slot_allocator_alloc (&slot_allocator,
4866  slot_p);
4867 }
4868 
4880 void
4882 {
4883  _dbus_return_if_fail (*slot_p >= 0);
4884 
4885  _dbus_data_slot_allocator_free (&slot_allocator, slot_p);
4886 }
4887 
4903  dbus_int32_t slot,
4904  void *data,
4905  DBusFreeFunction free_data_func)
4906 {
4907  DBusFreeFunction old_free_func;
4908  void *old_data;
4909  dbus_bool_t retval;
4910 
4911  _dbus_return_val_if_fail (message != NULL, FALSE);
4912  _dbus_return_val_if_fail (slot >= 0, FALSE);
4913 
4914  retval = _dbus_data_slot_list_set (&slot_allocator,
4915  &message->slot_list,
4916  slot, data, free_data_func,
4917  &old_free_func, &old_data);
4918 
4919  if (retval)
4920  {
4921  /* Do the actual free outside the message lock */
4922  if (old_free_func)
4923  (* old_free_func) (old_data);
4924  }
4925 
4926  return retval;
4927 }
4928 
4937 void*
4939  dbus_int32_t slot)
4940 {
4941  void *res;
4942 
4943  _dbus_return_val_if_fail (message != NULL, NULL);
4944 
4945  res = _dbus_data_slot_list_get (&slot_allocator,
4946  &message->slot_list,
4947  slot);
4948 
4949  return res;
4950 }
4951 
4965 int
4966 dbus_message_type_from_string (const char *type_str)
4967 {
4968  if (strcmp (type_str, "method_call") == 0)
4970  if (strcmp (type_str, "method_return") == 0)
4972  else if (strcmp (type_str, "signal") == 0)
4973  return DBUS_MESSAGE_TYPE_SIGNAL;
4974  else if (strcmp (type_str, "error") == 0)
4975  return DBUS_MESSAGE_TYPE_ERROR;
4976  else
4978 }
4979 
4993 const char *
4995 {
4996  switch (type)
4997  {
4999  return "method_call";
5001  return "method_return";
5003  return "signal";
5005  return "error";
5006  default:
5007  return "invalid";
5008  }
5009 }
5010 
5025  char **marshalled_data_p,
5026  int *len_p)
5027 {
5028  DBusString tmp;
5029  dbus_bool_t was_locked;
5030 
5031  _dbus_return_val_if_fail (msg != NULL, FALSE);
5032  _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
5033  _dbus_return_val_if_fail (len_p != NULL, FALSE);
5034 
5035  if (!_dbus_string_init (&tmp))
5036  return FALSE;
5037 
5038  /* Ensure the message is locked, to ensure the length header is filled in. */
5039  was_locked = msg->locked;
5040 
5041  if (!was_locked)
5042  dbus_message_lock (msg);
5043 
5044  if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
5045  goto fail;
5046 
5047  *len_p = _dbus_string_get_length (&tmp);
5048 
5049  if (!_dbus_string_copy (&(msg->body), 0, &tmp, *len_p))
5050  goto fail;
5051 
5052  *len_p = _dbus_string_get_length (&tmp);
5053 
5054  if (!_dbus_string_steal_data (&tmp, marshalled_data_p))
5055  goto fail;
5056 
5057  _dbus_string_free (&tmp);
5058 
5059  if (!was_locked)
5060  msg->locked = FALSE;
5061 
5062  return TRUE;
5063 
5064  fail:
5065  _dbus_string_free (&tmp);
5066 
5067  if (!was_locked)
5068  msg->locked = FALSE;
5069 
5070  return FALSE;
5071 }
5072 
5085 DBusMessage *
5086 dbus_message_demarshal (const char *str,
5087  int len,
5088  DBusError *error)
5089 {
5090  DBusMessageLoader *loader;
5091  DBusString *buffer;
5092  DBusMessage *msg;
5093 
5094  _dbus_return_val_if_fail (str != NULL, NULL);
5095 
5096  loader = _dbus_message_loader_new ();
5097 
5098  if (loader == NULL)
5099  return NULL;
5100 
5101  _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL);
5102 
5103  if (!_dbus_string_append_len (buffer, str, len))
5104  goto fail_oom;
5105 
5106  _dbus_message_loader_return_buffer (loader, buffer);
5107 
5109  goto fail_oom;
5110 
5112  goto fail_corrupt;
5113 
5114  msg = _dbus_message_loader_pop_message (loader);
5115 
5116  if (!msg)
5117  goto fail_oom;
5118 
5119  _dbus_message_loader_unref (loader);
5120  return msg;
5121 
5122  fail_corrupt:
5123  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
5124  _dbus_validity_to_error_message (loader->corruption_reason));
5125  _dbus_message_loader_unref (loader);
5126  return NULL;
5127 
5128  fail_oom:
5129  _DBUS_SET_OOM (error);
5130  _dbus_message_loader_unref (loader);
5131  return NULL;
5132 }
5133 
5146 int
5148  int len)
5149 {
5150  DBusString str;
5151  int byte_order, fields_array_len, header_len, body_len;
5152  DBusValidity validity = DBUS_VALID;
5153  int have_message;
5154 
5155  if (!buf || len < DBUS_MINIMUM_HEADER_SIZE)
5156  return 0;
5157 
5158  if (len > DBUS_MAXIMUM_MESSAGE_LENGTH)
5160  _dbus_string_init_const_len (&str, buf, len);
5161 
5162  validity = DBUS_VALID;
5163  have_message
5165  &validity, &byte_order,
5166  &fields_array_len,
5167  &header_len,
5168  &body_len,
5169  &str, 0,
5170  len);
5171  _dbus_string_free (&str);
5172 
5173  if (validity == DBUS_VALID)
5174  {
5175  _dbus_assert (have_message || (header_len + body_len) > len);
5176  (void) have_message; /* unused unless asserting */
5177  return header_len + body_len;
5178  }
5179  else
5180  {
5181  return -1; /* broken! */
5182  }
5183 }
5184 
5206 void
5208  dbus_bool_t allow)
5209 {
5210  _dbus_return_if_fail (message != NULL);
5211  _dbus_return_if_fail (!message->locked);
5212 
5213  _dbus_header_toggle_flag (&message->header,
5215  allow);
5216 }
5217 
5226 {
5227  _dbus_return_val_if_fail (message != NULL, FALSE);
5228 
5229  return _dbus_header_get_flag (&message->header,
5231 }
5232 
5240 {
5241  DBusString data;
5242 };
5243 
5255 DBusVariant *
5257 {
5258  DBusVariant *self = NULL;
5259  /* Points to the single item we will read from the reader */
5260  DBusMessageRealIter *real_reader = (DBusMessageRealIter *) reader;
5261  /* The position in self at which we will write a single variant
5262  * (it is position 0) */
5263  DBusTypeWriter items_writer;
5264  /* The position in self at which we will write a copy of reader
5265  * (it is inside the variant) */
5266  DBusTypeWriter variant_writer;
5267  /* 'v' */
5268  DBusString variant_signature;
5269  /* Whatever is the signature of the item we will copy from the reader */
5270  DBusString contained_signature;
5271  /* TRUE if self->data needs to be freed */
5272  dbus_bool_t data_inited = FALSE;
5273  /* The type of the item we will read from the reader */
5274  int type;
5275  /* The string, start position within that string, and length of the signature
5276  * of the single complete type of the item reader points to */
5277  const DBusString *sig;
5278  int start, len;
5279 
5280  _dbus_assert (_dbus_message_iter_check (real_reader));
5281  _dbus_assert (real_reader->iter_type == DBUS_MESSAGE_ITER_TYPE_READER);
5283  type = dbus_message_iter_get_arg_type (reader);
5284  _dbus_type_reader_get_signature (&real_reader->u.reader, &sig, &start, &len);
5285 
5286  if (!_dbus_string_init (&contained_signature))
5287  return NULL;
5288 
5289  if (!_dbus_string_copy_len (sig, start, len, &contained_signature, 0))
5290  goto oom;
5291 
5292  self = dbus_new0 (DBusVariant, 1);
5293 
5294  if (self == NULL)
5295  goto oom;
5296 
5297  if (!_dbus_string_init (&self->data))
5298  goto oom;
5299 
5300  data_inited = TRUE;
5301 
5302  _dbus_type_writer_init_values_only (&items_writer, DBUS_COMPILER_BYTE_ORDER,
5303  &variant_signature, 0, &self->data, 0);
5304 
5305  if (!_dbus_type_writer_recurse (&items_writer, DBUS_TYPE_VARIANT,
5306  &contained_signature, 0, &variant_writer))
5307  goto oom;
5308 
5309  if (type == DBUS_TYPE_ARRAY)
5310  {
5311  /* Points to each item in turn inside the array we are copying */
5312  DBusMessageIter array_reader;
5313  /* Same as array_reader */
5314  DBusMessageRealIter *real_array_reader = (DBusMessageRealIter *) &array_reader;
5315  /* The position inside the copied array at which we will write
5316  * the copy of array_reader */
5317  DBusTypeWriter array_writer;
5318 
5319  dbus_message_iter_recurse (reader, &array_reader);
5320 
5321  if (!_dbus_type_writer_recurse (&variant_writer, type,
5322  &contained_signature, 1, &array_writer))
5323  goto oom;
5324 
5325  if (!_dbus_type_writer_write_reader (&array_writer,
5326  &real_array_reader->u.reader))
5327  goto oom;
5328 
5329  if (!_dbus_type_writer_unrecurse (&variant_writer, &array_writer))
5330  goto oom;
5331  }
5332  else if (type == DBUS_TYPE_DICT_ENTRY || type == DBUS_TYPE_VARIANT ||
5333  type == DBUS_TYPE_STRUCT)
5334  {
5335  /* Points to each item in turn inside the container we are copying */
5336  DBusMessageIter inner_reader;
5337  /* Same as inner_reader */
5338  DBusMessageRealIter *real_inner_reader = (DBusMessageRealIter *) &inner_reader;
5339  /* The position inside the copied container at which we will write the
5340  * copy of inner_reader */
5341  DBusTypeWriter inner_writer;
5342 
5343  dbus_message_iter_recurse (reader, &inner_reader);
5344 
5345  if (!_dbus_type_writer_recurse (&variant_writer, type, NULL, 0,
5346  &inner_writer))
5347  goto oom;
5348 
5349  if (!_dbus_type_writer_write_reader (&inner_writer,
5350  &real_inner_reader->u.reader))
5351  goto oom;
5352 
5353  if (!_dbus_type_writer_unrecurse (&variant_writer, &inner_writer))
5354  goto oom;
5355  }
5356  else
5357  {
5358  DBusBasicValue value;
5359 
5360  /* We eliminated all the container types above */
5362 
5363  dbus_message_iter_get_basic (reader, &value);
5364 
5365  if (!_dbus_type_writer_write_basic (&variant_writer, type, &value))
5366  goto oom;
5367  }
5368 
5369  _dbus_string_free (&contained_signature);
5370  return self;
5371 
5372 oom:
5373  if (self != NULL)
5374  {
5375  if (data_inited)
5376  _dbus_string_free (&self->data);
5377 
5378  dbus_free (self);
5379  }
5380 
5381  _dbus_string_free (&contained_signature);
5382  return NULL;
5383 }
5384 
5391 const char *
5393 {
5394  unsigned char len;
5395  const char *ret;
5396 
5397  _dbus_assert (self != NULL);
5398 
5399  /* Here we make use of the fact that the serialization of a variant starts
5400  * with the 1-byte length, then that many bytes of signature, then \0. */
5401  len = _dbus_string_get_byte (&self->data, 0);
5402  ret = _dbus_string_get_const_data_len (&self->data, 1, len);
5403  _dbus_assert (strlen (ret) == len);
5404  return ret;
5405 }
5406 
5420  DBusMessageIter *writer)
5421 {
5422  /* 'v' */
5423  DBusString variant_signature;
5424  /* Points to the single item in self */
5425  DBusTypeReader variant_reader;
5426  /* Points to the single item (of whatever type) inside the variant */
5427  DBusTypeReader reader;
5428  /* The position at which we will copy reader */
5429  DBusMessageRealIter *real_writer = (DBusMessageRealIter *) writer;
5430  dbus_bool_t ret;
5431 
5432  _dbus_assert (self != NULL);
5433  _dbus_assert (_dbus_message_iter_append_check (real_writer));
5434  _dbus_assert (real_writer->iter_type == DBUS_MESSAGE_ITER_TYPE_WRITER);
5435 
5437  _dbus_type_reader_init (&reader, DBUS_COMPILER_BYTE_ORDER,
5438  &variant_signature, 0, &self->data, 0);
5439  _dbus_type_reader_recurse (&reader, &variant_reader);
5440 
5441  if (!_dbus_message_iter_open_signature (real_writer))
5442  return FALSE;
5443 
5444  ret = _dbus_type_writer_write_reader (&real_writer->u.writer,
5445  &variant_reader);
5446 
5447  if (!_dbus_message_iter_close_signature (real_writer))
5448  return FALSE;
5449 
5450  return ret;
5451 }
5452 
5453 int
5454 _dbus_variant_get_length (DBusVariant *self)
5455 {
5456  _dbus_assert (self != NULL);
5457  return _dbus_string_get_length (&self->data);
5458 }
5459 
5460 const DBusString *
5461 _dbus_variant_peek (DBusVariant *self)
5462 {
5463  _dbus_assert (self != NULL);
5464  return &self->data;
5465 }
5466 
5467 void
5468 _dbus_variant_free (DBusVariant *self)
5469 {
5470  _dbus_assert (self != NULL);
5471  _dbus_string_free (&self->data);
5472  dbus_free (self);
5473 }
5474 
5477 /* tests in dbus-message-util.c */