D-Bus  1.12.2
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] = {
87 };
88 
90 #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type)
91 
93 #define MAX_POSSIBLE_HEADER_PADDING 7
94 static dbus_bool_t
95 reserve_header_padding (DBusHeader *header)
96 {
98 
99  if (!_dbus_string_lengthen (&header->data,
101  return FALSE;
103  return TRUE;
104 }
105 
106 static void
107 correct_header_padding (DBusHeader *header)
108 {
109  int unpadded_len;
110 
111  _dbus_assert (header->padding == 7);
112 
113  _dbus_string_shorten (&header->data, header->padding);
114  unpadded_len = _dbus_string_get_length (&header->data);
115 
116  if (!_dbus_string_align_length (&header->data, 8))
117  _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");
118 
119  header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
120 }
121 
123 #define HEADER_END_BEFORE_PADDING(header) \
124  (_dbus_string_get_length (&(header)->data) - (header)->padding)
125 
133 static void
134 _dbus_header_cache_invalidate_all (DBusHeader *header)
135 {
136  int i;
137 
138  i = 0;
139  while (i <= DBUS_HEADER_FIELD_LAST)
140  {
141  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN;
142  ++i;
143  }
144 }
145 
153 static void
154 _dbus_header_cache_one (DBusHeader *header,
155  int field_code,
156  DBusTypeReader *variant_reader)
157 {
158  header->fields[field_code].value_pos =
159  _dbus_type_reader_get_value_pos (variant_reader);
160 
161 #if 0
162  _dbus_verbose ("cached value_pos %d for field %d\n",
163  header->fields[field_code].value_pos, field_code)
164 #endif
165 }
166 
173 char
175 {
176  _dbus_assert (_dbus_string_get_length (&header->data) > BYTE_ORDER_OFFSET);
177 
178  return (char) _dbus_string_get_byte (&header->data, BYTE_ORDER_OFFSET);
179 }
180 
186 static void
187 _dbus_header_cache_revalidate (DBusHeader *header)
188 {
189  DBusTypeReader array;
190  DBusTypeReader reader;
191  int i;
192 
193  i = 0;
194  while (i <= DBUS_HEADER_FIELD_LAST)
195  {
196  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
197  ++i;
198  }
199 
200  _dbus_type_reader_init (&reader,
202  &_dbus_header_signature_str,
204  &header->data,
206 
207  _dbus_type_reader_recurse (&reader, &array);
208 
210  {
211  DBusTypeReader sub;
212  DBusTypeReader variant;
213  unsigned char field_code;
214 
215  _dbus_type_reader_recurse (&array, &sub);
216 
218  _dbus_type_reader_read_basic (&sub, &field_code);
219 
220  /* Unknown fields should be ignored */
221  if (field_code > DBUS_HEADER_FIELD_LAST)
222  goto next_field;
223 
224  _dbus_type_reader_next (&sub);
225 
227  _dbus_type_reader_recurse (&sub, &variant);
228 
229  _dbus_header_cache_one (header, field_code, &variant);
230 
231  next_field:
232  _dbus_type_reader_next (&array);
233  }
234 }
235 
243 static dbus_bool_t
244 _dbus_header_cache_check (DBusHeader *header,
245  int field)
246 {
248 
249  if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
250  _dbus_header_cache_revalidate (header);
251 
252  if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
253  return FALSE;
254 
255  return TRUE;
256 }
257 
266 static dbus_bool_t
267 _dbus_header_cache_known_nonexistent (DBusHeader *header,
268  int field)
269 {
271 
272  return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
273 }
274 
284 static dbus_bool_t
285 write_basic_field (DBusTypeWriter *writer,
286  int field,
287  int type,
288  const void *value)
289 {
290  DBusTypeWriter sub;
291  DBusTypeWriter variant;
292  int start;
293  int padding;
294  unsigned char field_byte;
295  DBusString contained_type;
296  char buf[2];
297 
298  start = writer->value_pos;
299  padding = _dbus_string_get_length (writer->value_str) - start;
300 
302  NULL, 0, &sub))
303  goto append_failed;
304 
305  field_byte = field;
307  &field_byte))
308  goto append_failed;
309 
310  buf[0] = type;
311  buf[1] = '\0';
312  _dbus_string_init_const_len (&contained_type, buf, 1);
313 
315  &contained_type, 0, &variant))
316  goto append_failed;
317 
318  if (!_dbus_type_writer_write_basic (&variant, type, value))
319  goto append_failed;
320 
321  if (!_dbus_type_writer_unrecurse (&sub, &variant))
322  goto append_failed;
323 
324  if (!_dbus_type_writer_unrecurse (writer, &sub))
325  goto append_failed;
326 
327  return TRUE;
328 
329  append_failed:
331  start,
332  _dbus_string_get_length (writer->value_str) - start - padding);
333  return FALSE;
334 }
335 
346 static dbus_bool_t
347 set_basic_field (DBusTypeReader *reader,
348  int field,
349  int type,
350  const void *value,
351  const DBusTypeReader *realign_root)
352 {
353  DBusTypeReader sub;
354  DBusTypeReader variant;
355 
356  _dbus_type_reader_recurse (reader, &sub);
357 
359 #ifndef DBUS_DISABLE_ASSERT
360  {
361  unsigned char v_BYTE;
362  _dbus_type_reader_read_basic (&sub, &v_BYTE);
363  _dbus_assert (((int) v_BYTE) == field);
364  }
365 #endif
366 
367  if (!_dbus_type_reader_next (&sub))
368  _dbus_assert_not_reached ("no variant field?");
369 
370  _dbus_type_reader_recurse (&sub, &variant);
372 
373  if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
374  return FALSE;
375 
376  return TRUE;
377 }
378 
385 int
387 {
388  int type;
389 
390  type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
392 
393  return type;
394 }
395 
403 void
405  dbus_uint32_t serial)
406 {
407  /* we use this function to set the serial on outgoing
408  * messages, and to reset the serial in dbus_message_copy;
409  * this assertion should catch a double-set on outgoing.
410  */
411  _dbus_assert (_dbus_header_get_serial (header) == 0 ||
412  serial == 0);
413 
414  _dbus_marshal_set_uint32 (&header->data,
416  serial,
417  _dbus_header_get_byte_order (header));
418 }
419 
428 {
429  return _dbus_marshal_read_uint32 (&header->data,
432  NULL);
433 }
434 
442 void
444 {
445  _dbus_string_set_length (&header->data, 0);
446 
447  header->padding = 0;
448 
449  _dbus_header_cache_invalidate_all (header);
450 }
451 
461 {
462  if (!_dbus_string_init_preallocated (&header->data, 32))
463  return FALSE;
464 
465  _dbus_header_reinit (header);
466 
467  return TRUE;
468 }
469 
475 void
477 {
478  _dbus_string_free (&header->data);
479 }
480 
491  DBusHeader *dest)
492 {
493  *dest = *header;
494 
496  _dbus_string_get_length (&header->data)))
497  return FALSE;
498 
499  if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
500  {
501  _dbus_string_free (&dest->data);
502  return FALSE;
503  }
504 
505  /* Reset the serial */
506  _dbus_header_set_serial (dest, 0);
507 
508  return TRUE;
509 }
510 
529  int byte_order,
530  int message_type,
531  const char *destination,
532  const char *path,
533  const char *interface,
534  const char *member,
535  const char *error_name)
536 {
537  unsigned char v_BYTE;
538  dbus_uint32_t v_UINT32;
539  DBusTypeWriter writer;
540  DBusTypeWriter array;
541 
542  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
543  byte_order == DBUS_BIG_ENDIAN);
544  _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
545  (error_name) ||
546  !(interface || member || error_name));
547  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
548 
549  if (!reserve_header_padding (header))
550  return FALSE;
551 
552  _dbus_type_writer_init_values_only (&writer, byte_order,
553  &_dbus_header_signature_str, 0,
554  &header->data,
555  HEADER_END_BEFORE_PADDING (header));
556 
557  v_BYTE = byte_order;
559  &v_BYTE))
560  goto oom;
561 
562  v_BYTE = message_type;
564  &v_BYTE))
565  goto oom;
566 
567  v_BYTE = 0; /* flags */
569  &v_BYTE))
570  goto oom;
571 
574  &v_BYTE))
575  goto oom;
576 
577  v_UINT32 = 0; /* body length */
579  &v_UINT32))
580  goto oom;
581 
582  v_UINT32 = 0; /* serial */
584  &v_UINT32))
585  goto oom;
586 
588  &_dbus_header_signature_str,
590  &array))
591  goto oom;
592 
593  /* Marshal all the fields (Marshall Fields?) */
594 
595  if (path != NULL)
596  {
597  if (!write_basic_field (&array,
600  &path))
601  goto oom;
602  }
603 
604  if (destination != NULL)
605  {
606  if (!write_basic_field (&array,
609  &destination))
610  goto oom;
611  }
612 
613  if (interface != NULL)
614  {
615  if (!write_basic_field (&array,
618  &interface))
619  goto oom;
620  }
621 
622  if (member != NULL)
623  {
624  if (!write_basic_field (&array,
627  &member))
628  goto oom;
629  }
630 
631  if (error_name != NULL)
632  {
633  if (!write_basic_field (&array,
636  &error_name))
637  goto oom;
638  }
639 
640  if (!_dbus_type_writer_unrecurse (&writer, &array))
641  goto oom;
642 
643  correct_header_padding (header);
644 
645  return TRUE;
646 
647  oom:
648  _dbus_string_delete (&header->data, 0,
649  _dbus_string_get_length (&header->data) - header->padding);
650  correct_header_padding (header);
651 
652  return FALSE;
653 }
654 
673 _dbus_header_have_message_untrusted (int max_message_length,
674  DBusValidity *validity,
675  int *byte_order,
676  int *fields_array_len,
677  int *header_len,
678  int *body_len,
679  const DBusString *str,
680  int start,
681  int len)
682 
683 {
684  dbus_uint32_t header_len_unsigned;
685  dbus_uint32_t fields_array_len_unsigned;
686  dbus_uint32_t body_len_unsigned;
687 
688  _dbus_assert (start >= 0);
689  _dbus_assert (start < _DBUS_INT32_MAX / 2);
690  _dbus_assert (len >= 0);
691 
692  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
693 
694  *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
695 
696  if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
697  {
698  *validity = DBUS_INVALID_BAD_BYTE_ORDER;
699  return FALSE;
700  }
701 
703  fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
704  *byte_order, NULL);
705 
706  if (fields_array_len_unsigned > (unsigned) max_message_length)
707  {
708  *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
709  return FALSE;
710  }
711 
712  _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
713  body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
714  *byte_order, NULL);
715 
716  if (body_len_unsigned > (unsigned) max_message_length)
717  {
718  *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
719  return FALSE;
720  }
721 
722  header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
723  header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
724 
725  /* overflow should be impossible since the lengths aren't allowed to
726  * be huge.
727  */
728  _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2);
729  if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
730  {
731  *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
732  return FALSE;
733  }
734 
735  _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX);
736  _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX);
737  _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX);
738 
739  *body_len = body_len_unsigned;
740  *fields_array_len = fields_array_len_unsigned;
741  *header_len = header_len_unsigned;
742 
743  *validity = DBUS_VALID;
744 
745  _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
746  len, body_len_unsigned, header_len_unsigned,
747  body_len_unsigned + header_len_unsigned);
748 
749  return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
750 }
751 
752 static DBusValidity
753 check_mandatory_fields (DBusHeader *header)
754 {
755 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
756 
757  switch (_dbus_header_get_message_type (header))
758  {
760  REQUIRE_FIELD (INTERFACE);
761  /* FALL THRU - signals also require the path and member */
763  REQUIRE_FIELD (PATH);
764  REQUIRE_FIELD (MEMBER);
765  break;
767  REQUIRE_FIELD (ERROR_NAME);
768  REQUIRE_FIELD (REPLY_SERIAL);
769  break;
771  REQUIRE_FIELD (REPLY_SERIAL);
772  break;
773  default:
774  /* other message types allowed but ignored */
775  break;
776  }
777 
778  return DBUS_VALID;
779 }
780 
781 static DBusValidity
782 load_and_validate_field (DBusHeader *header,
783  int field,
784  DBusTypeReader *variant_reader)
785 {
786  int type;
787  int expected_type;
788  const DBusString *value_str;
789  int value_pos;
790  int str_data_pos;
791  dbus_uint32_t v_UINT32;
792  int bad_string_code;
793  dbus_bool_t (* string_validation_func) (const DBusString *str,
794  int start, int len);
795 
796  /* Supposed to have been checked already */
799 
800  /* Before we can cache a field, we need to know it has the right type */
801  type = _dbus_type_reader_get_current_type (variant_reader);
802 
803  _dbus_assert (_dbus_header_field_types[field].code == field);
804 
805  expected_type = EXPECTED_TYPE_OF_FIELD (field);
806  if (type != expected_type)
807  {
808  _dbus_verbose ("Field %d should have type %d but has %d\n",
809  field, expected_type, type);
810  return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
811  }
812 
813  /* If the field was provided twice, we aren't happy */
814  if (header->fields[field].value_pos >= 0)
815  {
816  _dbus_verbose ("Header field %d seen a second time\n", field);
817  return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
818  }
819 
820  /* Now we can cache and look at the field content */
821  _dbus_verbose ("initially caching field %d\n", field);
822  _dbus_header_cache_one (header, field, variant_reader);
823 
824  string_validation_func = NULL;
825 
826  /* make compiler happy that all this is initialized */
827  v_UINT32 = 0;
828  value_str = NULL;
829  value_pos = -1;
830  str_data_pos = -1;
831  bad_string_code = DBUS_VALID;
832 
833  if (expected_type == DBUS_TYPE_UINT32)
834  {
835  _dbus_header_get_field_basic (header, field, expected_type,
836  &v_UINT32);
837  }
838  else if (expected_type == DBUS_TYPE_STRING ||
839  expected_type == DBUS_TYPE_OBJECT_PATH ||
840  expected_type == DBUS_TYPE_SIGNATURE)
841  {
842  _dbus_header_get_field_raw (header, field,
843  &value_str, &value_pos);
844  str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
845  }
846  else
847  {
848  _dbus_assert_not_reached ("none of the known fields should have this type");
849  }
850 
851  switch (field)
852  {
854  string_validation_func = _dbus_validate_bus_name;
855  bad_string_code = DBUS_INVALID_BAD_DESTINATION;
856  break;
858  string_validation_func = _dbus_validate_interface;
859  bad_string_code = DBUS_INVALID_BAD_INTERFACE;
860 
861  if (_dbus_string_equal_substring (&_dbus_local_interface_str,
862  0,
863  _dbus_string_get_length (&_dbus_local_interface_str),
864  value_str, str_data_pos))
865  {
866  _dbus_verbose ("Message is on the local interface\n");
867  return DBUS_INVALID_USES_LOCAL_INTERFACE;
868  }
869  break;
870 
872  string_validation_func = _dbus_validate_member;
873  bad_string_code = DBUS_INVALID_BAD_MEMBER;
874  break;
875 
877  string_validation_func = _dbus_validate_error_name;
878  bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
879  break;
880 
882  string_validation_func = _dbus_validate_bus_name;
883  bad_string_code = DBUS_INVALID_BAD_SENDER;
884  break;
885 
887  /* OBJECT_PATH was validated generically due to its type */
888  string_validation_func = NULL;
889 
890  if (_dbus_string_equal_substring (&_dbus_local_path_str,
891  0,
892  _dbus_string_get_length (&_dbus_local_path_str),
893  value_str, str_data_pos))
894  {
895  _dbus_verbose ("Message is from the local path\n");
896  return DBUS_INVALID_USES_LOCAL_PATH;
897  }
898  break;
899 
901  /* Can't be 0 */
902  if (v_UINT32 == 0)
903  {
904  return DBUS_INVALID_BAD_SERIAL;
905  }
906  break;
907 
909  /* Every value makes sense */
910  break;
911 
913  /* SIGNATURE validated generically due to its type */
914  string_validation_func = NULL;
915  break;
916 
917  default:
918  _dbus_assert_not_reached ("unknown field shouldn't be seen here");
919  break;
920  }
921 
922  if (string_validation_func)
923  {
924  dbus_uint32_t len;
925 
926  _dbus_assert (bad_string_code != DBUS_VALID);
927 
928  len = _dbus_marshal_read_uint32 (value_str, value_pos,
930  NULL);
931 
932 #if 0
933  _dbus_verbose ("Validating string header field; code %d if fails\n",
934  bad_string_code);
935 #endif
936  if (!(*string_validation_func) (value_str, str_data_pos, len))
937  return bad_string_code;
938  }
939 
940  return DBUS_VALID;
941 }
942 
971  DBusValidationMode mode,
972  DBusValidity *validity,
973  int byte_order,
974  int fields_array_len,
975  int header_len,
976  int body_len,
977  const DBusString *str,
978  int start,
979  int len)
980 {
981  int leftover;
982  DBusValidity v;
983  DBusTypeReader reader;
984  DBusTypeReader array_reader;
985  unsigned char v_byte;
986  dbus_uint32_t v_uint32;
987  dbus_uint32_t serial;
988  int padding_start;
989  int padding_len;
990  int i;
991 
992  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
993  _dbus_assert (header_len <= len);
994  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
995 
996  if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
997  {
998  _dbus_verbose ("Failed to copy buffer into new header\n");
1000  return FALSE;
1001  }
1002 
1003  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1004  {
1005  leftover = len - header_len - body_len - start;
1006  }
1007  else
1008  {
1009  v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
1010  byte_order,
1011  &leftover,
1012  str, start, len);
1013 
1014  if (v != DBUS_VALID)
1015  {
1016  *validity = v;
1017  goto invalid;
1018  }
1019  }
1020 
1021  _dbus_assert (leftover < len);
1022 
1023  padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
1024  padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
1025  _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
1026  _dbus_assert (start + header_len == padding_start + padding_len);
1027 
1028  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1029  {
1030  if (!_dbus_string_validate_nul (str, padding_start, padding_len))
1031  {
1032  *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1033  goto invalid;
1034  }
1035  }
1036 
1037  header->padding = padding_len;
1038 
1039  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1040  {
1041  *validity = DBUS_VALID;
1042  return TRUE;
1043  }
1044 
1045  /* We now know the data is well-formed, but we have to check that
1046  * it's valid.
1047  */
1048 
1049  _dbus_type_reader_init (&reader,
1050  byte_order,
1051  &_dbus_header_signature_str, 0,
1052  str, start);
1053 
1054  /* BYTE ORDER */
1057  _dbus_type_reader_read_basic (&reader, &v_byte);
1058  _dbus_type_reader_next (&reader);
1059 
1060  _dbus_assert (v_byte == byte_order);
1061 
1062  /* MESSAGE TYPE */
1065  _dbus_type_reader_read_basic (&reader, &v_byte);
1066  _dbus_type_reader_next (&reader);
1067 
1068  /* unknown message types are supposed to be ignored, so only validation here is
1069  * that it isn't invalid
1070  */
1071  if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1072  {
1073  *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1074  goto invalid;
1075  }
1076 
1077  /* FLAGS */
1080  _dbus_type_reader_read_basic (&reader, &v_byte);
1081  _dbus_type_reader_next (&reader);
1082 
1083  /* unknown flags should be ignored */
1084 
1085  /* PROTOCOL VERSION */
1088  _dbus_type_reader_read_basic (&reader, &v_byte);
1089  _dbus_type_reader_next (&reader);
1090 
1091  if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1092  {
1093  *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1094  goto invalid;
1095  }
1096 
1097  /* BODY LENGTH */
1100  _dbus_type_reader_read_basic (&reader, &v_uint32);
1101  _dbus_type_reader_next (&reader);
1102 
1103  _dbus_assert (body_len == (signed) v_uint32);
1104 
1105  /* SERIAL */
1108  _dbus_type_reader_read_basic (&reader, &serial);
1109  _dbus_type_reader_next (&reader);
1110 
1111  if (serial == 0)
1112  {
1113  *validity = DBUS_INVALID_BAD_SERIAL;
1114  goto invalid;
1115  }
1116 
1119 
1120  _dbus_type_reader_recurse (&reader, &array_reader);
1121  while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1122  {
1123  DBusTypeReader struct_reader;
1124  DBusTypeReader variant_reader;
1125  unsigned char field_code;
1126 
1128 
1129  _dbus_type_reader_recurse (&array_reader, &struct_reader);
1130 
1132  _dbus_type_reader_read_basic (&struct_reader, &field_code);
1133  _dbus_type_reader_next (&struct_reader);
1134 
1135  if (field_code == DBUS_HEADER_FIELD_INVALID)
1136  {
1137  _dbus_verbose ("invalid header field code\n");
1138  *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1139  goto invalid;
1140  }
1141 
1142  if (field_code > DBUS_HEADER_FIELD_LAST)
1143  {
1144  _dbus_verbose ("unknown header field code %d, skipping\n",
1145  field_code);
1146  goto next_field;
1147  }
1148 
1150  _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1151 
1152  v = load_and_validate_field (header, field_code, &variant_reader);
1153  if (v != DBUS_VALID)
1154  {
1155  _dbus_verbose ("Field %d was invalid\n", field_code);
1156  *validity = v;
1157  goto invalid;
1158  }
1159 
1160  next_field:
1161  _dbus_type_reader_next (&array_reader);
1162  }
1163 
1164  /* Anything we didn't fill in is now known not to exist */
1165  i = 0;
1166  while (i <= DBUS_HEADER_FIELD_LAST)
1167  {
1168  if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1169  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1170  ++i;
1171  }
1172 
1173  v = check_mandatory_fields (header);
1174  if (v != DBUS_VALID)
1175  {
1176  _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1177  *validity = v;
1178  goto invalid;
1179  }
1180 
1181  *validity = DBUS_VALID;
1182  return TRUE;
1183 
1184  invalid:
1185  _dbus_string_set_length (&header->data, 0);
1186  return FALSE;
1187 }
1188 
1195 void
1197  int body_len)
1198 {
1199  _dbus_marshal_set_uint32 (&header->data,
1201  body_len,
1202  _dbus_header_get_byte_order (header));
1203 }
1204 
1218 static dbus_bool_t
1219 find_field_for_modification (DBusHeader *header,
1220  int field,
1221  DBusTypeReader *reader,
1222  DBusTypeReader *realign_root)
1223 {
1224  dbus_bool_t retval;
1225 
1226  retval = FALSE;
1227 
1228  _dbus_type_reader_init (realign_root,
1229  _dbus_header_get_byte_order (header),
1230  &_dbus_header_signature_str,
1232  &header->data,
1234 
1235  _dbus_type_reader_recurse (realign_root, reader);
1236 
1238  {
1239  DBusTypeReader sub;
1240  unsigned char field_code;
1241 
1242  _dbus_type_reader_recurse (reader, &sub);
1243 
1245  _dbus_type_reader_read_basic (&sub, &field_code);
1246 
1247  if (field_code == (unsigned) field)
1248  {
1250  retval = TRUE;
1251  goto done;
1252  }
1253 
1254  _dbus_type_reader_next (reader);
1255  }
1256 
1257  done:
1258  return retval;
1259 }
1260 
1274  int field,
1275  int type,
1276  const void *value)
1277 {
1279 
1280  if (!reserve_header_padding (header))
1281  return FALSE;
1282 
1283  /* If the field exists we set, otherwise we append */
1284  if (_dbus_header_cache_check (header, field))
1285  {
1286  DBusTypeReader reader;
1287  DBusTypeReader realign_root;
1288 
1289  if (!find_field_for_modification (header, field,
1290  &reader, &realign_root))
1291  _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1292 
1293  if (!set_basic_field (&reader, field, type, value, &realign_root))
1294  return FALSE;
1295  }
1296  else
1297  {
1298  DBusTypeWriter writer;
1299  DBusTypeWriter array;
1300 
1302  _dbus_header_get_byte_order (header),
1303  &_dbus_header_signature_str,
1305  &header->data,
1307 
1308  /* recurse into array without creating a new length, and jump to
1309  * end of array.
1310  */
1311  if (!_dbus_type_writer_append_array (&writer,
1312  &_dbus_header_signature_str,
1314  &array))
1315  _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1316 
1317  _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1318  _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1319  _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1320 
1321  if (!write_basic_field (&array,
1322  field, type, value))
1323  return FALSE;
1324 
1325  if (!_dbus_type_writer_unrecurse (&writer, &array))
1326  _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1327  }
1328 
1329  correct_header_padding (header);
1330 
1331  /* We could be smarter about this (only invalidate fields after the
1332  * one we modified, or even only if the one we modified changed
1333  * length). But this hack is a start.
1334  */
1335  _dbus_header_cache_invalidate_all (header);
1336 
1337  return TRUE;
1338 }
1339 
1352  int field,
1353  int type,
1354  void *value)
1355 {
1358  _dbus_assert (_dbus_header_field_types[field].code == field);
1359  /* in light of this you might ask why the type is passed in;
1360  * the only rationale I can think of is so the caller has
1361  * to specify its expectation and breaks if we change it
1362  */
1363  _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1364 
1365  if (!_dbus_header_cache_check (header, field))
1366  return FALSE;
1367 
1368  _dbus_assert (header->fields[field].value_pos >= 0);
1369 
1370  _dbus_marshal_read_basic (&header->data,
1371  header->fields[field].value_pos,
1372  type, value, _dbus_header_get_byte_order (header),
1373  NULL);
1374 
1375  return TRUE;
1376 }
1377 
1393  int field,
1394  const DBusString **str,
1395  int *pos)
1396 {
1397  if (!_dbus_header_cache_check (header, field))
1398  return FALSE;
1399 
1400  if (str)
1401  *str = &header->data;
1402  if (pos)
1403  *pos = header->fields[field].value_pos;
1404 
1405  return TRUE;
1406 }
1407 
1417  int field)
1418 {
1419  DBusTypeReader reader;
1420  DBusTypeReader realign_root;
1421 
1422  if (_dbus_header_cache_known_nonexistent (header, field))
1423  return TRUE; /* nothing to do */
1424 
1425  /* Scan to the field we want, delete and realign, reappend
1426  * padding. Field may turn out not to exist.
1427  */
1428  if (!find_field_for_modification (header, field,
1429  &reader, &realign_root))
1430  return TRUE; /* nothing to do */
1431 
1432  if (!reserve_header_padding (header))
1433  return FALSE;
1434 
1435  if (!_dbus_type_reader_delete (&reader,
1436  &realign_root))
1437  return FALSE;
1438 
1439  correct_header_padding (header);
1440 
1441  _dbus_header_cache_invalidate_all (header);
1442 
1443  _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1444 
1445  return TRUE;
1446 }
1447 
1456 void
1458  dbus_uint32_t flag,
1459  dbus_bool_t value)
1460 {
1461  unsigned char *flags_p;
1462 
1463  flags_p = _dbus_string_get_udata_len (&header->data, FLAGS_OFFSET, 1);
1464 
1465  if (value)
1466  *flags_p |= flag;
1467  else
1468  *flags_p &= ~flag;
1469 }
1470 
1480  dbus_uint32_t flag)
1481 {
1482  const unsigned char *flags_p;
1483 
1484  flags_p = _dbus_string_get_const_udata_len (&header->data, FLAGS_OFFSET, 1);
1485 
1486  return (*flags_p & flag) != 0;
1487 }
1488 
1495 void
1497  int new_order)
1498 {
1499  char byte_order;
1500 
1501  byte_order = _dbus_header_get_byte_order (header);
1502 
1503  if (byte_order == new_order)
1504  return;
1505 
1506  _dbus_marshal_byteswap (&_dbus_header_signature_str,
1507  0, byte_order,
1508  new_order,
1509  &header->data, 0);
1510 
1511  _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order);
1512 }
1513 
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...
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
#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.