D-Bus  1.12.20
dbus-marshal-header.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-marshal-header.c Managing marshaling/demarshaling of message headers
3  *
4  * Copyright (C) 2005 Red Hat, Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23 
24 #include <config.h>
25 #include "dbus/dbus-shared.h"
26 #include "dbus-marshal-header.h"
27 #include "dbus-marshal-recursive.h"
28 #include "dbus-marshal-byteswap.h"
29 
37 /* Not thread locked, but strictly const/read-only so should be OK
38  */
40 _DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE);
42 _DBUS_STRING_DEFINE_STATIC(_dbus_local_interface_str, DBUS_INTERFACE_LOCAL);
44 _DBUS_STRING_DEFINE_STATIC(_dbus_local_path_str, DBUS_PATH_LOCAL);
45 
47 #define FIELDS_ARRAY_SIGNATURE_OFFSET 6
48 
49 #define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET 7
50 
51 
53 #define BYTE_ORDER_OFFSET 0
54 
55 #define TYPE_OFFSET 1
56 
57 #define FLAGS_OFFSET 2
58 
59 #define VERSION_OFFSET 3
60 
61 #define BODY_LENGTH_OFFSET 4
62 
63 #define SERIAL_OFFSET 8
64 
65 #define FIELDS_ARRAY_LENGTH_OFFSET 12
66 
67 #define FIRST_FIELD_OFFSET 16
68 
69 typedef struct
70 {
71  unsigned char code;
72  unsigned char type;
74 
75 static const HeaderFieldType
76 _dbus_header_field_types[DBUS_HEADER_FIELD_LAST+1] = {
80  { DBUS_HEADER_FIELD_MEMBER, DBUS_TYPE_STRING },
81  { DBUS_HEADER_FIELD_ERROR_NAME, DBUS_TYPE_STRING },
83  { DBUS_HEADER_FIELD_DESTINATION, DBUS_TYPE_STRING },
84  { DBUS_HEADER_FIELD_SENDER, DBUS_TYPE_STRING },
86  { DBUS_HEADER_FIELD_UNIX_FDS, DBUS_TYPE_UINT32 }
87 #ifdef HAVE_PDPLINUX
88  ,{ DBUS_HEADER_FIELD_EXEC_SRC, DBUS_TYPE_STRING }
89  ,{ DBUS_HEADER_FIELD_EXEC_DST, DBUS_TYPE_STRING }
90 #endif
91 };
92 
94 #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type)
95 
97 #define MAX_POSSIBLE_HEADER_PADDING 7
98 static dbus_bool_t
99 reserve_header_padding (DBusHeader *header)
100 {
102 
103  if (!_dbus_string_lengthen (&header->data,
105  return FALSE;
107  return TRUE;
108 }
109 
110 static void
111 correct_header_padding (DBusHeader *header)
112 {
113  int unpadded_len;
114 
115  _dbus_assert (header->padding == 7);
116 
117  _dbus_string_shorten (&header->data, header->padding);
118  unpadded_len = _dbus_string_get_length (&header->data);
119 
120  if (!_dbus_string_align_length (&header->data, 8))
121  _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");
122 
123  header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
124 }
125 
127 #define HEADER_END_BEFORE_PADDING(header) \
128  (_dbus_string_get_length (&(header)->data) - (header)->padding)
129 
137 static void
138 _dbus_header_cache_invalidate_all (DBusHeader *header)
139 {
140  int i;
141 
142  i = 0;
143  while (i <= DBUS_HEADER_FIELD_LAST)
144  {
145  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN;
146  ++i;
147  }
148 }
149 
157 static void
158 _dbus_header_cache_one (DBusHeader *header,
159  int field_code,
160  DBusTypeReader *variant_reader)
161 {
162  header->fields[field_code].value_pos =
163  _dbus_type_reader_get_value_pos (variant_reader);
164 
165 #if 0
166  _dbus_verbose ("cached value_pos %d for field %d\n",
167  header->fields[field_code].value_pos, field_code)
168 #endif
169 }
170 
177 char
179 {
180  _dbus_assert (_dbus_string_get_length (&header->data) > BYTE_ORDER_OFFSET);
181 
182  return (char) _dbus_string_get_byte (&header->data, BYTE_ORDER_OFFSET);
183 }
184 
190 static void
191 _dbus_header_cache_revalidate (DBusHeader *header)
192 {
193  DBusTypeReader array;
194  DBusTypeReader reader;
195  int i;
196 
197  i = 0;
198  while (i <= DBUS_HEADER_FIELD_LAST)
199  {
200  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
201  ++i;
202  }
203 
204  _dbus_type_reader_init (&reader,
206  &_dbus_header_signature_str,
208  &header->data,
210 
211  _dbus_type_reader_recurse (&reader, &array);
212 
214  {
215  DBusTypeReader sub;
216  DBusTypeReader variant;
217  unsigned char field_code;
218 
219  _dbus_type_reader_recurse (&array, &sub);
220 
222  _dbus_type_reader_read_basic (&sub, &field_code);
223 
224  /* Unknown fields should be ignored */
225  if (field_code > DBUS_HEADER_FIELD_LAST)
226  goto next_field;
227 
228  _dbus_type_reader_next (&sub);
229 
231  _dbus_type_reader_recurse (&sub, &variant);
232 
233  _dbus_header_cache_one (header, field_code, &variant);
234 
235  next_field:
236  _dbus_type_reader_next (&array);
237  }
238 }
239 
247 static dbus_bool_t
248 _dbus_header_cache_check (DBusHeader *header,
249  int field)
250 {
252 
253  if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
254  _dbus_header_cache_revalidate (header);
255 
256  if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
257  return FALSE;
258 
259  return TRUE;
260 }
261 
270 static dbus_bool_t
271 _dbus_header_cache_known_nonexistent (DBusHeader *header,
272  int field)
273 {
275 
276  return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
277 }
278 
288 static dbus_bool_t
289 write_basic_field (DBusTypeWriter *writer,
290  int field,
291  int type,
292  const void *value)
293 {
294  DBusTypeWriter sub;
295  DBusTypeWriter variant;
296  int start;
297  int padding;
298  unsigned char field_byte;
299  DBusString contained_type;
300  char buf[2];
301 
302  start = writer->value_pos;
303  padding = _dbus_string_get_length (writer->value_str) - start;
304 
306  NULL, 0, &sub))
307  goto append_failed;
308 
309  field_byte = field;
311  &field_byte))
312  goto append_failed;
313 
314  buf[0] = type;
315  buf[1] = '\0';
316  _dbus_string_init_const_len (&contained_type, buf, 1);
317 
319  &contained_type, 0, &variant))
320  goto append_failed;
321 
322  if (!_dbus_type_writer_write_basic (&variant, type, value))
323  goto append_failed;
324 
325  if (!_dbus_type_writer_unrecurse (&sub, &variant))
326  goto append_failed;
327 
328  if (!_dbus_type_writer_unrecurse (writer, &sub))
329  goto append_failed;
330 
331  return TRUE;
332 
333  append_failed:
335  start,
336  _dbus_string_get_length (writer->value_str) - start - padding);
337  return FALSE;
338 }
339 
350 static dbus_bool_t
351 set_basic_field (DBusTypeReader *reader,
352  int field,
353  int type,
354  const void *value,
355  const DBusTypeReader *realign_root)
356 {
357  DBusTypeReader sub;
358  DBusTypeReader variant;
359 
360  _dbus_type_reader_recurse (reader, &sub);
361 
363 #ifndef DBUS_DISABLE_ASSERT
364  {
365  unsigned char v_BYTE;
366  _dbus_type_reader_read_basic (&sub, &v_BYTE);
367  _dbus_assert (((int) v_BYTE) == field);
368  }
369 #endif
370 
371  if (!_dbus_type_reader_next (&sub))
372  _dbus_assert_not_reached ("no variant field?");
373 
374  _dbus_type_reader_recurse (&sub, &variant);
376 
377  if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
378  return FALSE;
379 
380  return TRUE;
381 }
382 
389 int
391 {
392  int type;
393 
394  type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
396 
397  return type;
398 }
399 
407 void
409  dbus_uint32_t serial)
410 {
411  /* we use this function to set the serial on outgoing
412  * messages, and to reset the serial in dbus_message_copy;
413  * this assertion should catch a double-set on outgoing.
414  */
415  _dbus_assert (_dbus_header_get_serial (header) == 0 ||
416  serial == 0);
417 
418  _dbus_marshal_set_uint32 (&header->data,
420  serial,
421  _dbus_header_get_byte_order (header));
422 }
423 
430 dbus_uint32_t
432 {
433  return _dbus_marshal_read_uint32 (&header->data,
436  NULL);
437 }
438 
446 void
448 {
449  _dbus_string_set_length (&header->data, 0);
450 
451  header->padding = 0;
452 
453  _dbus_header_cache_invalidate_all (header);
454 }
455 
465 {
466  if (!_dbus_string_init_preallocated (&header->data, 32))
467  return FALSE;
468 
469  _dbus_header_reinit (header);
470 
471  return TRUE;
472 }
473 
479 void
481 {
482  _dbus_string_free (&header->data);
483 }
484 
495  DBusHeader *dest)
496 {
497  *dest = *header;
498 
500  _dbus_string_get_length (&header->data)))
501  return FALSE;
502 
503  if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
504  {
505  _dbus_string_free (&dest->data);
506  return FALSE;
507  }
508 
509  /* Reset the serial */
510  _dbus_header_set_serial (dest, 0);
511 
512  return TRUE;
513 }
514 
533  int byte_order,
534  int message_type,
535  const char *destination,
536  const char *path,
537  const char *interface,
538  const char *member,
539  const char *error_name)
540 {
541  unsigned char v_BYTE;
542  dbus_uint32_t v_UINT32;
543  DBusTypeWriter writer;
544  DBusTypeWriter array;
545 
546  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
547  byte_order == DBUS_BIG_ENDIAN);
548  _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
549  (error_name) ||
550  !(interface || member || error_name));
551  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
552 
553  if (!reserve_header_padding (header))
554  return FALSE;
555 
556  _dbus_type_writer_init_values_only (&writer, byte_order,
557  &_dbus_header_signature_str, 0,
558  &header->data,
559  HEADER_END_BEFORE_PADDING (header));
560 
561  v_BYTE = byte_order;
563  &v_BYTE))
564  goto oom;
565 
566  v_BYTE = message_type;
568  &v_BYTE))
569  goto oom;
570 
571  v_BYTE = 0; /* flags */
573  &v_BYTE))
574  goto oom;
575 
578  &v_BYTE))
579  goto oom;
580 
581  v_UINT32 = 0; /* body length */
583  &v_UINT32))
584  goto oom;
585 
586  v_UINT32 = 0; /* serial */
588  &v_UINT32))
589  goto oom;
590 
592  &_dbus_header_signature_str,
594  &array))
595  goto oom;
596 
597  /* Marshal all the fields (Marshall Fields?) */
598 
599  if (path != NULL)
600  {
601  if (!write_basic_field (&array,
604  &path))
605  goto oom;
606  }
607 
608  if (destination != NULL)
609  {
610  if (!write_basic_field (&array,
613  &destination))
614  goto oom;
615  }
616 
617  if (interface != NULL)
618  {
619  if (!write_basic_field (&array,
622  &interface))
623  goto oom;
624  }
625 
626  if (member != NULL)
627  {
628  if (!write_basic_field (&array,
631  &member))
632  goto oom;
633  }
634 
635  if (error_name != NULL)
636  {
637  if (!write_basic_field (&array,
640  &error_name))
641  goto oom;
642  }
643 
644  if (!_dbus_type_writer_unrecurse (&writer, &array))
645  goto oom;
646 
647  correct_header_padding (header);
648 
649  return TRUE;
650 
651  oom:
652  _dbus_string_delete (&header->data, 0,
653  _dbus_string_get_length (&header->data) - header->padding);
654  correct_header_padding (header);
655 
656  return FALSE;
657 }
658 
677 _dbus_header_have_message_untrusted (int max_message_length,
678  DBusValidity *validity,
679  int *byte_order,
680  int *fields_array_len,
681  int *header_len,
682  int *body_len,
683  const DBusString *str,
684  int start,
685  int len)
686 
687 {
688  dbus_uint32_t header_len_unsigned;
689  dbus_uint32_t fields_array_len_unsigned;
690  dbus_uint32_t body_len_unsigned;
691 
692  _dbus_assert (start >= 0);
693  _dbus_assert (start < _DBUS_INT32_MAX / 2);
694  _dbus_assert (len >= 0);
695 
696  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
697 
698  *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
699 
700  if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
701  {
702  *validity = DBUS_INVALID_BAD_BYTE_ORDER;
703  return FALSE;
704  }
705 
707  fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
708  *byte_order, NULL);
709 
710  if (fields_array_len_unsigned > (unsigned) max_message_length)
711  {
712  *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
713  return FALSE;
714  }
715 
716  _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
717  body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
718  *byte_order, NULL);
719 
720  if (body_len_unsigned > (unsigned) max_message_length)
721  {
722  *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
723  return FALSE;
724  }
725 
726  header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
727  header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
728 
729  /* overflow should be impossible since the lengths aren't allowed to
730  * be huge.
731  */
732  _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2);
733  if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
734  {
735  *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
736  return FALSE;
737  }
738 
739  _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX);
740  _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX);
741  _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX);
742 
743  *body_len = body_len_unsigned;
744  *fields_array_len = fields_array_len_unsigned;
745  *header_len = header_len_unsigned;
746 
747  *validity = DBUS_VALID;
748 
749  _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
750  len, body_len_unsigned, header_len_unsigned,
751  body_len_unsigned + header_len_unsigned);
752 
753  return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
754 }
755 
756 static DBusValidity
757 check_mandatory_fields (DBusHeader *header)
758 {
759 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
760 
761  switch (_dbus_header_get_message_type (header))
762  {
764  REQUIRE_FIELD (INTERFACE);
765  /* FALL THRU - signals also require the path and member */
767  REQUIRE_FIELD (PATH);
768  REQUIRE_FIELD (MEMBER);
769  break;
771  REQUIRE_FIELD (ERROR_NAME);
772  REQUIRE_FIELD (REPLY_SERIAL);
773  break;
775  REQUIRE_FIELD (REPLY_SERIAL);
776  break;
777  default:
778  /* other message types allowed but ignored */
779  break;
780  }
781 
782  return DBUS_VALID;
783 }
784 
785 static DBusValidity
786 load_and_validate_field (DBusHeader *header,
787  int field,
788  DBusTypeReader *variant_reader)
789 {
790  int type;
791  int expected_type;
792  const DBusString *value_str;
793  int value_pos;
794  int str_data_pos;
795  dbus_uint32_t v_UINT32;
796  int bad_string_code;
797  dbus_bool_t (* string_validation_func) (const DBusString *str,
798  int start, int len);
799 
800  /* Supposed to have been checked already */
803 
804  /* Before we can cache a field, we need to know it has the right type */
805  type = _dbus_type_reader_get_current_type (variant_reader);
806 
807  _dbus_assert (_dbus_header_field_types[field].code == field);
808 
809  expected_type = EXPECTED_TYPE_OF_FIELD (field);
810  if (type != expected_type)
811  {
812  _dbus_verbose ("Field %d should have type %d but has %d\n",
813  field, expected_type, type);
814  return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
815  }
816 
817  /* If the field was provided twice, we aren't happy */
818  if (header->fields[field].value_pos >= 0)
819  {
820  _dbus_verbose ("Header field %d seen a second time\n", field);
821  return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
822  }
823 
824  /* Now we can cache and look at the field content */
825  _dbus_verbose ("initially caching field %d\n", field);
826  _dbus_header_cache_one (header, field, variant_reader);
827 
828  string_validation_func = NULL;
829 
830  /* make compiler happy that all this is initialized */
831  v_UINT32 = 0;
832  value_str = NULL;
833  value_pos = -1;
834  str_data_pos = -1;
835  bad_string_code = DBUS_VALID;
836 
837  if (expected_type == DBUS_TYPE_UINT32)
838  {
839  _dbus_header_get_field_basic (header, field, expected_type,
840  &v_UINT32);
841  }
842  else if (expected_type == DBUS_TYPE_STRING ||
843  expected_type == DBUS_TYPE_OBJECT_PATH ||
844  expected_type == DBUS_TYPE_SIGNATURE)
845  {
846  _dbus_header_get_field_raw (header, field,
847  &value_str, &value_pos);
848  str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
849  }
850  else
851  {
852  _dbus_assert_not_reached ("none of the known fields should have this type");
853  }
854 
855  switch (field)
856  {
858  string_validation_func = _dbus_validate_bus_name;
859  bad_string_code = DBUS_INVALID_BAD_DESTINATION;
860  break;
862  string_validation_func = _dbus_validate_interface;
863  bad_string_code = DBUS_INVALID_BAD_INTERFACE;
864 
865  if (_dbus_string_equal_substring (&_dbus_local_interface_str,
866  0,
867  _dbus_string_get_length (&_dbus_local_interface_str),
868  value_str, str_data_pos))
869  {
870  _dbus_verbose ("Message is on the local interface\n");
871  return DBUS_INVALID_USES_LOCAL_INTERFACE;
872  }
873  break;
874 
876  string_validation_func = _dbus_validate_member;
877  bad_string_code = DBUS_INVALID_BAD_MEMBER;
878  break;
879 
881  string_validation_func = _dbus_validate_error_name;
882  bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
883  break;
884 
886  string_validation_func = _dbus_validate_bus_name;
887  bad_string_code = DBUS_INVALID_BAD_SENDER;
888  break;
889 
891  /* OBJECT_PATH was validated generically due to its type */
892  string_validation_func = NULL;
893 
894  if (_dbus_string_equal_substring (&_dbus_local_path_str,
895  0,
896  _dbus_string_get_length (&_dbus_local_path_str),
897  value_str, str_data_pos))
898  {
899  _dbus_verbose ("Message is from the local path\n");
900  return DBUS_INVALID_USES_LOCAL_PATH;
901  }
902  break;
903 
905  /* Can't be 0 */
906  if (v_UINT32 == 0)
907  {
908  return DBUS_INVALID_BAD_SERIAL;
909  }
910  break;
911 
913  /* Every value makes sense */
914  break;
915 
916 #ifdef HAVE_PDPLINUX
917  case DBUS_HEADER_FIELD_EXEC_SRC:
918  /* Every value makes sense */
919  break;
920  case DBUS_HEADER_FIELD_EXEC_DST:
921  /* Every value makes sense */
922  break;
923 #endif
924 
926  /* SIGNATURE validated generically due to its type */
927  string_validation_func = NULL;
928  break;
929 
930  default:
931  _dbus_assert_not_reached ("unknown field shouldn't be seen here");
932  break;
933  }
934 
935  if (string_validation_func)
936  {
937  dbus_uint32_t len;
938 
939  _dbus_assert (bad_string_code != DBUS_VALID);
940 
941  len = _dbus_marshal_read_uint32 (value_str, value_pos,
943  NULL);
944 
945 #if 0
946  _dbus_verbose ("Validating string header field; code %d if fails\n",
947  bad_string_code);
948 #endif
949  if (!(*string_validation_func) (value_str, str_data_pos, len))
950  return bad_string_code;
951  }
952 
953  return DBUS_VALID;
954 }
955 
984  DBusValidationMode mode,
985  DBusValidity *validity,
986  int byte_order,
987  int fields_array_len,
988  int header_len,
989  int body_len,
990  const DBusString *str,
991  int start,
992  int len)
993 {
994  int leftover;
995  DBusValidity v;
996  DBusTypeReader reader;
997  DBusTypeReader array_reader;
998  unsigned char v_byte;
999  dbus_uint32_t v_uint32;
1000  dbus_uint32_t serial;
1001  int padding_start;
1002  int padding_len;
1003  int i;
1004 
1005  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
1006  _dbus_assert (header_len <= len);
1007  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
1008 
1009  if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
1010  {
1011  _dbus_verbose ("Failed to copy buffer into new header\n");
1012  *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
1013  return FALSE;
1014  }
1015 
1016  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1017  {
1018  leftover = len - header_len - body_len - start;
1019  }
1020  else
1021  {
1022  v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
1023  byte_order,
1024  &leftover,
1025  str, start, len);
1026 
1027  if (v != DBUS_VALID)
1028  {
1029  *validity = v;
1030  goto invalid;
1031  }
1032  }
1033 
1034  _dbus_assert (leftover < len);
1035 
1036  padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
1037  padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
1038  _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
1039  _dbus_assert (start + header_len == padding_start + padding_len);
1040 
1041  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1042  {
1043  if (!_dbus_string_validate_nul (str, padding_start, padding_len))
1044  {
1045  *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1046  goto invalid;
1047  }
1048  }
1049 
1050  header->padding = padding_len;
1051 
1052  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1053  {
1054  *validity = DBUS_VALID;
1055  return TRUE;
1056  }
1057 
1058  /* We now know the data is well-formed, but we have to check that
1059  * it's valid.
1060  */
1061 
1062  _dbus_type_reader_init (&reader,
1063  byte_order,
1064  &_dbus_header_signature_str, 0,
1065  str, start);
1066 
1067  /* BYTE ORDER */
1070  _dbus_type_reader_read_basic (&reader, &v_byte);
1071  _dbus_type_reader_next (&reader);
1072 
1073  _dbus_assert (v_byte == byte_order);
1074 
1075  /* MESSAGE TYPE */
1078  _dbus_type_reader_read_basic (&reader, &v_byte);
1079  _dbus_type_reader_next (&reader);
1080 
1081  /* unknown message types are supposed to be ignored, so only validation here is
1082  * that it isn't invalid
1083  */
1084  if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1085  {
1086  *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1087  goto invalid;
1088  }
1089 
1090  /* FLAGS */
1093  _dbus_type_reader_read_basic (&reader, &v_byte);
1094  _dbus_type_reader_next (&reader);
1095 
1096  /* unknown flags should be ignored */
1097 
1098  /* PROTOCOL VERSION */
1101  _dbus_type_reader_read_basic (&reader, &v_byte);
1102  _dbus_type_reader_next (&reader);
1103 
1104  if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1105  {
1106  *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1107  goto invalid;
1108  }
1109 
1110  /* BODY LENGTH */
1113  _dbus_type_reader_read_basic (&reader, &v_uint32);
1114  _dbus_type_reader_next (&reader);
1115 
1116  _dbus_assert (body_len == (signed) v_uint32);
1117 
1118  /* SERIAL */
1121  _dbus_type_reader_read_basic (&reader, &serial);
1122  _dbus_type_reader_next (&reader);
1123 
1124  if (serial == 0)
1125  {
1126  *validity = DBUS_INVALID_BAD_SERIAL;
1127  goto invalid;
1128  }
1129 
1132 
1133  _dbus_type_reader_recurse (&reader, &array_reader);
1134  while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1135  {
1136  DBusTypeReader struct_reader;
1137  DBusTypeReader variant_reader;
1138  unsigned char field_code;
1139 
1141 
1142  _dbus_type_reader_recurse (&array_reader, &struct_reader);
1143 
1145  _dbus_type_reader_read_basic (&struct_reader, &field_code);
1146  _dbus_type_reader_next (&struct_reader);
1147 
1148  if (field_code == DBUS_HEADER_FIELD_INVALID)
1149  {
1150  _dbus_verbose ("invalid header field code\n");
1151  *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1152  goto invalid;
1153  }
1154 
1155  if (field_code > DBUS_HEADER_FIELD_LAST)
1156  {
1157  _dbus_verbose ("unknown header field code %d, skipping\n",
1158  field_code);
1159  goto next_field;
1160  }
1161 
1163  _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1164 
1165  v = load_and_validate_field (header, field_code, &variant_reader);
1166  if (v != DBUS_VALID)
1167  {
1168  _dbus_verbose ("Field %d was invalid\n", field_code);
1169  *validity = v;
1170  goto invalid;
1171  }
1172 
1173  next_field:
1174  _dbus_type_reader_next (&array_reader);
1175  }
1176 
1177  /* Anything we didn't fill in is now known not to exist */
1178  i = 0;
1179  while (i <= DBUS_HEADER_FIELD_LAST)
1180  {
1181  if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1182  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1183  ++i;
1184  }
1185 
1186  v = check_mandatory_fields (header);
1187  if (v != DBUS_VALID)
1188  {
1189  _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1190  *validity = v;
1191  goto invalid;
1192  }
1193 
1194  *validity = DBUS_VALID;
1195  return TRUE;
1196 
1197  invalid:
1198  _dbus_string_set_length (&header->data, 0);
1199  return FALSE;
1200 }
1201 
1208 void
1210  int body_len)
1211 {
1212  _dbus_marshal_set_uint32 (&header->data,
1214  body_len,
1215  _dbus_header_get_byte_order (header));
1216 }
1217 
1231 static dbus_bool_t
1232 find_field_for_modification (DBusHeader *header,
1233  int field,
1234  DBusTypeReader *reader,
1235  DBusTypeReader *realign_root)
1236 {
1237  dbus_bool_t retval;
1238 
1239  retval = FALSE;
1240 
1241  _dbus_type_reader_init (realign_root,
1242  _dbus_header_get_byte_order (header),
1243  &_dbus_header_signature_str,
1245  &header->data,
1247 
1248  _dbus_type_reader_recurse (realign_root, reader);
1249 
1251  {
1252  DBusTypeReader sub;
1253  unsigned char field_code;
1254 
1255  _dbus_type_reader_recurse (reader, &sub);
1256 
1258  _dbus_type_reader_read_basic (&sub, &field_code);
1259 
1260  if (field_code == (unsigned) field)
1261  {
1263  retval = TRUE;
1264  goto done;
1265  }
1266 
1267  _dbus_type_reader_next (reader);
1268  }
1269 
1270  done:
1271  return retval;
1272 }
1273 
1287  int field,
1288  int type,
1289  const void *value)
1290 {
1292 
1293  if (!reserve_header_padding (header))
1294  return FALSE;
1295 
1296  /* If the field exists we set, otherwise we append */
1297  if (_dbus_header_cache_check (header, field))
1298  {
1299  DBusTypeReader reader;
1300  DBusTypeReader realign_root;
1301 
1302  if (!find_field_for_modification (header, field,
1303  &reader, &realign_root))
1304  _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1305 
1306  if (!set_basic_field (&reader, field, type, value, &realign_root))
1307  return FALSE;
1308  }
1309  else
1310  {
1311  DBusTypeWriter writer;
1312  DBusTypeWriter array;
1313 
1315  _dbus_header_get_byte_order (header),
1316  &_dbus_header_signature_str,
1318  &header->data,
1320 
1321  /* recurse into array without creating a new length, and jump to
1322  * end of array.
1323  */
1324  if (!_dbus_type_writer_append_array (&writer,
1325  &_dbus_header_signature_str,
1327  &array))
1328  _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1329 
1330  _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1331  _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1332  _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1333 
1334  if (!write_basic_field (&array,
1335  field, type, value))
1336  return FALSE;
1337 
1338  if (!_dbus_type_writer_unrecurse (&writer, &array))
1339  _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1340  }
1341 
1342  correct_header_padding (header);
1343 
1344  /* We could be smarter about this (only invalidate fields after the
1345  * one we modified, or even only if the one we modified changed
1346  * length). But this hack is a start.
1347  */
1348  _dbus_header_cache_invalidate_all (header);
1349 
1350  return TRUE;
1351 }
1352 
1365  int field,
1366  int type,
1367  void *value)
1368 {
1371  _dbus_assert (_dbus_header_field_types[field].code == field);
1372  /* in light of this you might ask why the type is passed in;
1373  * the only rationale I can think of is so the caller has
1374  * to specify its expectation and breaks if we change it
1375  */
1376  _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1377 
1378  if (!_dbus_header_cache_check (header, field))
1379  return FALSE;
1380 
1381  _dbus_assert (header->fields[field].value_pos >= 0);
1382 
1383  _dbus_marshal_read_basic (&header->data,
1384  header->fields[field].value_pos,
1385  type, value, _dbus_header_get_byte_order (header),
1386  NULL);
1387 
1388  return TRUE;
1389 }
1390 
1406  int field,
1407  const DBusString **str,
1408  int *pos)
1409 {
1410  if (!_dbus_header_cache_check (header, field))
1411  return FALSE;
1412 
1413  if (str)
1414  *str = &header->data;
1415  if (pos)
1416  *pos = header->fields[field].value_pos;
1417 
1418  return TRUE;
1419 }
1420 
1430  int field)
1431 {
1432  DBusTypeReader reader;
1433  DBusTypeReader realign_root;
1434 
1435  if (_dbus_header_cache_known_nonexistent (header, field))
1436  return TRUE; /* nothing to do */
1437 
1438  /* Scan to the field we want, delete and realign, reappend
1439  * padding. Field may turn out not to exist.
1440  */
1441  if (!find_field_for_modification (header, field,
1442  &reader, &realign_root))
1443  return TRUE; /* nothing to do */
1444 
1445  if (!reserve_header_padding (header))
1446  return FALSE;
1447 
1448  if (!_dbus_type_reader_delete (&reader,
1449  &realign_root))
1450  return FALSE;
1451 
1452  correct_header_padding (header);
1453 
1454  _dbus_header_cache_invalidate_all (header);
1455 
1456  _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1457 
1458  return TRUE;
1459 }
1460 
1469 void
1471  dbus_uint32_t flag,
1472  dbus_bool_t value)
1473 {
1474  unsigned char *flags_p;
1475 
1476  flags_p = _dbus_string_get_udata_len (&header->data, FLAGS_OFFSET, 1);
1477 
1478  if (value)
1479  *flags_p |= flag;
1480  else
1481  *flags_p &= ~flag;
1482 }
1483 
1493  dbus_uint32_t flag)
1494 {
1495  const unsigned char *flags_p;
1496 
1497  flags_p = _dbus_string_get_const_udata_len (&header->data, FLAGS_OFFSET, 1);
1498 
1499  return (*flags_p & flag) != 0;
1500 }
1501 
1508 void
1510  int new_order)
1511 {
1512  char byte_order;
1513 
1514  byte_order = _dbus_header_get_byte_order (header);
1515 
1516  if (byte_order == new_order)
1517  return;
1518 
1519  _dbus_marshal_byteswap (&_dbus_header_signature_str,
1520  0, byte_order,
1521  new_order,
1522  &header->data, 0);
1523 
1524  _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order);
1525 }
1526 
DBusValidity _dbus_validate_body_with_reason(const DBusString *expected_signature, int expected_signature_start, int byte_order, int *bytes_remaining, const DBusString *value_str, int value_pos, int len)
Verifies that the range of value_str from value_pos to value_end is a legitimate value of type expect...
#define DBUS_HEADER_FIELD_INVALID
Not equal to any valid header field code.
#define NULL
A null pointer, defined appropriately for C or C++.
dbus_bool_t _dbus_header_load(DBusHeader *header, DBusValidationMode mode, DBusValidity *validity, int byte_order, int fields_array_len, int header_len, int body_len, const DBusString *str, int start, int len)
Creates a message header from potentially-untrusted data.
dbus_bool_t _dbus_header_copy(const DBusHeader *header, DBusHeader *dest)
Initializes dest with a copy of the given header.
void _dbus_marshal_set_uint32(DBusString *str, int pos, dbus_uint32_t value, int byte_order)
Sets the 4 bytes at the given offset to a marshaled unsigned integer, replacing anything found there ...
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:760
The type writer is an iterator for writing to a block of values.
void _dbus_type_reader_recurse(DBusTypeReader *reader, DBusTypeReader *sub)
Initialize a new reader pointing to the first type and corresponding value that&#39;s a child of the curr...
#define DBUS_HEADER_FIELD_SIGNATURE
Header field code for the type signature of a message.
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can&#39;t appear in a type string...
dbus_uint32_t padding
bytes of alignment in header
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
dbus_uint32_t _dbus_header_get_serial(DBusHeader *header)
See dbus_message_get_serial()
dbus_bool_t _dbus_header_get_flag(DBusHeader *header, dbus_uint32_t flag)
Gets a message flag bit, returning TRUE if the bit is set.
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
dbus_bool_t _dbus_header_init(DBusHeader *header)
Initializes a header, but doesn&#39;t prepare it for use; to make the header valid, you have to call _dbu...
#define DBUS_HEADER_SIGNATURE
Header format is defined as a signature: byte byte order byte message type ID byte flags byte protoco...
#define DBUS_HEADER_FIELD_LAST
Value of the highest-numbered header field code, can be used to determine the size of an array indexe...
#define DBUS_TYPE_BYTE
Type code marking an 8-bit unsigned integer.
Definition: dbus-protocol.h:66
#define DBUS_INTERFACE_LOCAL
This is a special interface whose methods can only be invoked by the local implementation (messages f...
Definition: dbus-shared.h:105
dbus_bool_t _dbus_validate_interface(const DBusString *str, int start, int len)
Checks that the given range of the string is a valid interface name in the D-Bus protocol.
DBusString data
Header network data, stored separately from body so we can independently realloc it.
dbus_bool_t _dbus_type_writer_write_basic(DBusTypeWriter *writer, int type, const void *value)
Writes out a basic type.
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
Message type of a method return message, see dbus_message_get_type()
#define EXPECTED_TYPE_OF_FIELD(field)
Macro to look up the correct type for a field.
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:780
DBusValidationMode
This is used rather than a bool for high visibility.
dbus_bool_t _dbus_string_copy(const DBusString *source, int start, DBusString *dest, int insert_at)
Like _dbus_string_move(), but does not delete the section of the source string that&#39;s copied to the d...
Definition: dbus-string.c:1283
#define DBUS_HEADER_FIELD_INTERFACE
Header field code for the interface containing a member (method or signal).
DBusValidity
This is primarily used in unit testing, so we can verify that each invalid message is invalid for the...
dbus_bool_t _dbus_validate_member(const DBusString *str, int start, int len)
Checks that the given range of the string is a valid member name in the D-Bus protocol.
DBusString * value_str
where to write values
#define VERSION_OFFSET
Offset to version from start of header.
#define DBUS_PATH_LOCAL
The object path used in local/in-process-generated messages.
Definition: dbus-shared.h:82
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
#define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET
Offset from start of _dbus_header_signature_str to the signature of an element of the fields array...
#define DBUS_MAJOR_PROTOCOL_VERSION
Protocol version.
Definition: dbus-protocol.h:57
dbus_bool_t _dbus_validate_error_name(const DBusString *str, int start, int len)
Checks that the given range of the string is a valid error name in the D-Bus protocol.
#define BYTE_ORDER_OFFSET
Offset to byte order from start of header.
dbus_bool_t _dbus_type_reader_delete(DBusTypeReader *reader, const DBusTypeReader *realign_root)
Recursively deletes any value pointed to by the reader, leaving the reader valid to continue reading...
#define TYPE_OFFSET
Offset to type from start of header.
void _dbus_type_writer_init_values_only(DBusTypeWriter *writer, int byte_order, const DBusString *type_str, int type_pos, DBusString *value_str, int value_pos)
Like _dbus_type_writer_init(), except the type string passed in should correspond to an existing sign...
dbus_bool_t _dbus_type_reader_set_basic(DBusTypeReader *reader, const void *value, const DBusTypeReader *realign_root)
Sets a new value for the basic type value pointed to by the reader, leaving the reader valid to conti...
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
#define DBUS_HEADER_FIELD_ERROR_NAME
Header field code for an error name (found in DBUS_MESSAGE_TYPE_ERROR messages).
#define BODY_LENGTH_OFFSET
Offset to body length from start of header.
dbus_bool_t _dbus_type_writer_unrecurse(DBusTypeWriter *writer, DBusTypeWriter *sub)
Closes a container created by _dbus_type_writer_recurse() and writes any additional information to th...
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
void _dbus_type_reader_read_basic(const DBusTypeReader *reader, void *value)
Reads a basic-typed value, as with _dbus_marshal_read_basic().
int value_pos
Position of field value, or -1/-2.
#define SERIAL_OFFSET
Offset to client serial from start of header.
dbus_bool_t _dbus_header_get_field_basic(DBusHeader *header, int field, int type, void *value)
Gets the value of a field with basic type.
can&#39;t determine validity due to OOM
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1193
dbus_bool_t _dbus_string_init_preallocated(DBusString *str, int allocate_size)
Initializes a string that can be up to the given allocation size before it has to realloc...
Definition: dbus-string.c:132
dbus_bool_t _dbus_type_writer_append_array(DBusTypeWriter *writer, const DBusString *contained_type, int contained_type_start, DBusTypeWriter *sub)
Append to an existing array.
void _dbus_marshal_read_basic(const DBusString *str, int pos, int type, void *value, int byte_order, int *new_pos)
Demarshals a basic-typed value.
dbus_bool_t _dbus_type_reader_next(DBusTypeReader *reader)
Skip to the next value on this "level".
void _dbus_header_byteswap(DBusHeader *header, int new_order)
Swaps the header into the given order if required.
dbus_bool_t _dbus_header_have_message_untrusted(int max_message_length, DBusValidity *validity, int *byte_order, int *fields_array_len, int *header_len, int *body_len, const DBusString *str, int start, int len)
Given data long enough to contain the length of the message body and the fields array, check whether the data is long enough to contain the entire message (assuming the claimed lengths are accurate).
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
#define DBUS_HEADER_FIELD_UNIX_FDS
Header field code for the number of unix file descriptors associated with this message.
#define DBUS_BIG_ENDIAN
Code marking MSB-first byte order in the wire protocol.
Definition: dbus-protocol.h:54
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
dbus_bool_t _dbus_validate_bus_name(const DBusString *str, int start, int len)
Checks that the given range of the string is a valid bus name in the D-Bus protocol.
dbus_bool_t _dbus_string_align_length(DBusString *str, int alignment)
Align the length of a string to a specific alignment (typically 4 or 8) by appending nul bytes to the...
Definition: dbus-string.c:883
#define DBUS_MESSAGE_TYPE_SIGNAL
Message type of a signal message, see dbus_message_get_type()
dbus_bool_t _dbus_string_equal_substring(const DBusString *a, int a_start, int a_len, const DBusString *b, int b_start)
Tests two sub-parts of two DBusString for equality.
Definition: dbus-string.c:2104
#define FIRST_FIELD_OFFSET
Offset to first field in header.
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
#define HEADER_END_BEFORE_PADDING(header)
Compute the end of the header, ignoring padding.
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
void _dbus_header_reinit(DBusHeader *header)
Re-initializes a header that was previously initialized and never freed.
the data is valid
#define DBUS_HEADER_FIELD_DESTINATION
Header field code for the destination bus name of a message.
dbus_bool_t _dbus_header_delete_field(DBusHeader *header, int field)
Deletes a field, if it exists.
unsigned char type
the value type
#define MAX_POSSIBLE_HEADER_PADDING
The most padding we could ever need for a header.
#define DBUS_MESSAGE_TYPE_INVALID
This value is never a valid message type, see dbus_message_get_type()
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
The type reader is an iterator for reading values from a block of values.
#define TRUE
Expands to "1".
dbus_bool_t _dbus_header_set_field_basic(DBusHeader *header, int field, int type, const void *value)
Sets the value of a field with basic type.
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
#define DBUS_HEADER_FIELD_SENDER
Header field code for the sender of a message; usually initialized by the message bus...
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
dbus_bool_t _dbus_header_create(DBusHeader *header, int byte_order, int message_type, const char *destination, const char *path, const char *interface, const char *member, const char *error_name)
Fills in the primary fields of the header, so the header is ready for use.
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
unsigned char code
the field code
int value_pos
next position to write
void _dbus_type_reader_init(DBusTypeReader *reader, int byte_order, const DBusString *type_str, int type_pos, const DBusString *value_str, int value_pos)
Initializes a type reader.
void _dbus_header_free(DBusHeader *header)
Frees a header.
DBusHeaderField fields[DBUS_HEADER_FIELD_LAST+1]
Track the location of each field in header.
#define FIELDS_ARRAY_LENGTH_OFFSET
Offset to fields array length from start of header.
void _dbus_header_set_serial(DBusHeader *header, dbus_uint32_t serial)
Sets the serial number of a header.
char _dbus_header_get_byte_order(const DBusHeader *header)
Returns the header&#39;s byte order.
_DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE)
Static DBusString containing the signature of a message header.
union DBusTypeWriter::@3 u
class-specific data
#define _DBUS_INT32_MAX
Maximum value of type "int32".
dbus_bool_t _dbus_string_validate_nul(const DBusString *str, int start, int len)
Checks that the given range of the string is all nul bytes.
Definition: dbus-string.c:2653
dbus_bool_t _dbus_header_get_field_raw(DBusHeader *header, int field, const DBusString **str, int *pos)
Gets the raw marshaled data for a field.
int _dbus_type_reader_get_current_type(const DBusTypeReader *reader)
Gets the type of the value the reader is currently pointing to; or for a types-only reader gets the t...
#define FALSE
Expands to "0".
Message header data and some cached details of it.
#define DBUS_HEADER_FIELD_PATH
Header field code for the path - the path is the object emitting a signal or the object receiving a m...
#define DBUS_HEADER_FIELD_REPLY_SERIAL
Header field code for a reply serial, used to match a DBUS_MESSAGE_TYPE_METHOD_RETURN message with th...
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:802
#define FLAGS_OFFSET
Offset to flags from start of header.
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1375
void _dbus_string_init_const_len(DBusString *str, const char *value, int len)
Initializes a constant string with a length.
Definition: dbus-string.c:210
dbus_bool_t _dbus_type_writer_recurse(DBusTypeWriter *writer, int container_type, const DBusString *contained_type, int contained_type_start, DBusTypeWriter *sub)
Opens a new container and writes out the initial information for that container.
#define FIELDS_ARRAY_SIGNATURE_OFFSET
Offset from start of _dbus_header_signature_str to the signature of the fields array.
void _dbus_header_toggle_flag(DBusHeader *header, dbus_uint32_t flag, dbus_bool_t value)
Toggles a message flag bit, turning on the bit if value = TRUE and flipping it off if value = FALSE...
void _dbus_header_update_lengths(DBusHeader *header, int body_len)
Fills in the correct body length.
void _dbus_marshal_byteswap(const DBusString *signature, int signature_start, int old_byte_order, int new_byte_order, DBusString *value_str, int value_pos)
Byteswaps the marshaled data in the given value_str.
int _dbus_type_reader_get_value_pos(const DBusTypeReader *reader)
Gets the current position in the value block.
#define DBUS_LITTLE_ENDIAN
Code marking LSB-first byte order in the wire protocol.
Definition: dbus-protocol.h:53
dbus_uint32_t _dbus_marshal_read_uint32(const DBusString *str, int pos, int byte_order, int *new_pos)
Convenience function to demarshal a 32 bit unsigned integer.