D-Bus  1.6.12
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 {
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 
283 static dbus_bool_t
284 write_basic_field (DBusTypeWriter *writer,
285  int field,
286  int type,
287  const void *value)
288 {
289  DBusTypeWriter sub;
290  DBusTypeWriter variant;
291  int start;
292  int padding;
293  unsigned char field_byte;
294  DBusString contained_type;
295  char buf[2];
296 
297  start = writer->value_pos;
298  padding = _dbus_string_get_length (writer->value_str) - start;
299 
301  NULL, 0, &sub))
302  goto append_failed;
303 
304  field_byte = field;
306  &field_byte))
307  goto append_failed;
308 
309  buf[0] = type;
310  buf[1] = '\0';
311  _dbus_string_init_const_len (&contained_type, buf, 1);
312 
314  &contained_type, 0, &variant))
315  goto append_failed;
316 
317  if (!_dbus_type_writer_write_basic (&variant, type, value))
318  goto append_failed;
319 
320  if (!_dbus_type_writer_unrecurse (&sub, &variant))
321  goto append_failed;
322 
323  if (!_dbus_type_writer_unrecurse (writer, &sub))
324  goto append_failed;
325 
326  return TRUE;
327 
328  append_failed:
330  start,
331  _dbus_string_get_length (writer->value_str) - start - padding);
332  return FALSE;
333 }
334 
344 static dbus_bool_t
345 set_basic_field (DBusTypeReader *reader,
346  int field,
347  int type,
348  const void *value,
349  const DBusTypeReader *realign_root)
350 {
351  DBusTypeReader sub;
352  DBusTypeReader variant;
353 
354  _dbus_type_reader_recurse (reader, &sub);
355 
357 #ifndef DBUS_DISABLE_ASSERT
358  {
359  unsigned char v_BYTE;
360  _dbus_type_reader_read_basic (&sub, &v_BYTE);
361  _dbus_assert (((int) v_BYTE) == field);
362  }
363 #endif
364 
365  if (!_dbus_type_reader_next (&sub))
366  _dbus_assert_not_reached ("no variant field?");
367 
368  _dbus_type_reader_recurse (&sub, &variant);
370 
371  if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
372  return FALSE;
373 
374  return TRUE;
375 }
376 
383 int
385 {
386  int type;
387 
388  type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
390 
391  return type;
392 }
393 
401 void
403  dbus_uint32_t serial)
404 {
405  /* we use this function to set the serial on outgoing
406  * messages, and to reset the serial in dbus_message_copy;
407  * this assertion should catch a double-set on outgoing.
408  */
409  _dbus_assert (_dbus_header_get_serial (header) == 0 ||
410  serial == 0);
411 
412  _dbus_marshal_set_uint32 (&header->data,
414  serial,
415  _dbus_header_get_byte_order (header));
416 }
417 
426 {
427  return _dbus_marshal_read_uint32 (&header->data,
430  NULL);
431 }
432 
440 void
442 {
443  _dbus_string_set_length (&header->data, 0);
444 
445  header->padding = 0;
446 
447  _dbus_header_cache_invalidate_all (header);
448 }
449 
460 {
461  if (!_dbus_string_init_preallocated (&header->data, 32))
462  return FALSE;
463 
464  _dbus_header_reinit (header);
465 
466  return TRUE;
467 }
468 
474 void
476 {
477  _dbus_string_free (&header->data);
478 }
479 
490  DBusHeader *dest)
491 {
492  *dest = *header;
493 
495  _dbus_string_get_length (&header->data)))
496  return FALSE;
497 
498  if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
499  {
500  _dbus_string_free (&dest->data);
501  return FALSE;
502  }
503 
504  /* Reset the serial */
505  _dbus_header_set_serial (dest, 0);
506 
507  return TRUE;
508 }
509 
527  int byte_order,
528  int message_type,
529  const char *destination,
530  const char *path,
531  const char *interface,
532  const char *member,
533  const char *error_name)
534 {
535  unsigned char v_BYTE;
536  dbus_uint32_t v_UINT32;
537  DBusTypeWriter writer;
538  DBusTypeWriter array;
539 
540  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
541  byte_order == DBUS_BIG_ENDIAN);
542  _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
543  (error_name) ||
544  !(interface || member || error_name));
545  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
546 
547  if (!reserve_header_padding (header))
548  return FALSE;
549 
550  _dbus_type_writer_init_values_only (&writer, byte_order,
551  &_dbus_header_signature_str, 0,
552  &header->data,
553  HEADER_END_BEFORE_PADDING (header));
554 
555  v_BYTE = byte_order;
557  &v_BYTE))
558  goto oom;
559 
560  v_BYTE = message_type;
562  &v_BYTE))
563  goto oom;
564 
565  v_BYTE = 0; /* flags */
567  &v_BYTE))
568  goto oom;
569 
572  &v_BYTE))
573  goto oom;
574 
575  v_UINT32 = 0; /* body length */
577  &v_UINT32))
578  goto oom;
579 
580  v_UINT32 = 0; /* serial */
582  &v_UINT32))
583  goto oom;
584 
586  &_dbus_header_signature_str,
588  &array))
589  goto oom;
590 
591  /* Marshal all the fields (Marshall Fields?) */
592 
593  if (path != NULL)
594  {
595  if (!write_basic_field (&array,
598  &path))
599  goto oom;
600  }
601 
602  if (destination != NULL)
603  {
604  if (!write_basic_field (&array,
607  &destination))
608  goto oom;
609  }
610 
611  if (interface != NULL)
612  {
613  if (!write_basic_field (&array,
616  &interface))
617  goto oom;
618  }
619 
620  if (member != NULL)
621  {
622  if (!write_basic_field (&array,
625  &member))
626  goto oom;
627  }
628 
629  if (error_name != NULL)
630  {
631  if (!write_basic_field (&array,
634  &error_name))
635  goto oom;
636  }
637 
638  if (!_dbus_type_writer_unrecurse (&writer, &array))
639  goto oom;
640 
641  correct_header_padding (header);
642 
643  return TRUE;
644 
645  oom:
646  _dbus_string_delete (&header->data, 0,
647  _dbus_string_get_length (&header->data) - header->padding);
648  correct_header_padding (header);
649 
650  return FALSE;
651 }
652 
671 _dbus_header_have_message_untrusted (int max_message_length,
672  DBusValidity *validity,
673  int *byte_order,
674  int *fields_array_len,
675  int *header_len,
676  int *body_len,
677  const DBusString *str,
678  int start,
679  int len)
680 
681 {
682  dbus_uint32_t header_len_unsigned;
683  dbus_uint32_t fields_array_len_unsigned;
684  dbus_uint32_t body_len_unsigned;
685 
686  _dbus_assert (start >= 0);
687  _dbus_assert (start < _DBUS_INT32_MAX / 2);
688  _dbus_assert (len >= 0);
689 
690  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
691 
692  *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
693 
694  if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
695  {
696  *validity = DBUS_INVALID_BAD_BYTE_ORDER;
697  return FALSE;
698  }
699 
701  fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
702  *byte_order, NULL);
703 
704  if (fields_array_len_unsigned > (unsigned) max_message_length)
705  {
706  *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
707  return FALSE;
708  }
709 
710  _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
711  body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
712  *byte_order, NULL);
713 
714  if (body_len_unsigned > (unsigned) max_message_length)
715  {
716  *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
717  return FALSE;
718  }
719 
720  header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
721  header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
722 
723  /* overflow should be impossible since the lengths aren't allowed to
724  * be huge.
725  */
726  _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2);
727  if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
728  {
729  *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
730  return FALSE;
731  }
732 
733  _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX);
734  _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX);
735  _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX);
736 
737  *body_len = body_len_unsigned;
738  *fields_array_len = fields_array_len_unsigned;
739  *header_len = header_len_unsigned;
740 
741  *validity = DBUS_VALID;
742 
743  _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
744  len, body_len_unsigned, header_len_unsigned,
745  body_len_unsigned + header_len_unsigned);
746 
747  return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
748 }
749 
750 static DBusValidity
751 check_mandatory_fields (DBusHeader *header)
752 {
753 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
754 
755  switch (_dbus_header_get_message_type (header))
756  {
758  REQUIRE_FIELD (INTERFACE);
759  /* FALL THRU - signals also require the path and member */
761  REQUIRE_FIELD (PATH);
762  REQUIRE_FIELD (MEMBER);
763  break;
765  REQUIRE_FIELD (ERROR_NAME);
766  REQUIRE_FIELD (REPLY_SERIAL);
767  break;
769  REQUIRE_FIELD (REPLY_SERIAL);
770  break;
771  default:
772  /* other message types allowed but ignored */
773  break;
774  }
775 
776  return DBUS_VALID;
777 }
778 
779 static DBusValidity
780 load_and_validate_field (DBusHeader *header,
781  int field,
782  DBusTypeReader *variant_reader)
783 {
784  int type;
785  int expected_type;
786  const DBusString *value_str;
787  int value_pos;
788  int str_data_pos;
789  dbus_uint32_t v_UINT32;
790  int bad_string_code;
791  dbus_bool_t (* string_validation_func) (const DBusString *str,
792  int start, int len);
793 
794  /* Supposed to have been checked already */
797 
798  /* Before we can cache a field, we need to know it has the right type */
799  type = _dbus_type_reader_get_current_type (variant_reader);
800 
801  _dbus_assert (_dbus_header_field_types[field].code == field);
802 
803  expected_type = EXPECTED_TYPE_OF_FIELD (field);
804  if (type != expected_type)
805  {
806  _dbus_verbose ("Field %d should have type %d but has %d\n",
807  field, expected_type, type);
808  return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
809  }
810 
811  /* If the field was provided twice, we aren't happy */
812  if (header->fields[field].value_pos >= 0)
813  {
814  _dbus_verbose ("Header field %d seen a second time\n", field);
815  return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
816  }
817 
818  /* Now we can cache and look at the field content */
819  _dbus_verbose ("initially caching field %d\n", field);
820  _dbus_header_cache_one (header, field, variant_reader);
821 
822  string_validation_func = NULL;
823 
824  /* make compiler happy that all this is initialized */
825  v_UINT32 = 0;
826  value_str = NULL;
827  value_pos = -1;
828  str_data_pos = -1;
829  bad_string_code = DBUS_VALID;
830 
831  if (expected_type == DBUS_TYPE_UINT32)
832  {
833  _dbus_header_get_field_basic (header, field, expected_type,
834  &v_UINT32);
835  }
836  else if (expected_type == DBUS_TYPE_STRING ||
837  expected_type == DBUS_TYPE_OBJECT_PATH ||
838  expected_type == DBUS_TYPE_SIGNATURE)
839  {
840  _dbus_header_get_field_raw (header, field,
841  &value_str, &value_pos);
842  str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
843  }
844  else
845  {
846  _dbus_assert_not_reached ("none of the known fields should have this type");
847  }
848 
849  switch (field)
850  {
852  string_validation_func = _dbus_validate_bus_name;
853  bad_string_code = DBUS_INVALID_BAD_DESTINATION;
854  break;
856  string_validation_func = _dbus_validate_interface;
857  bad_string_code = DBUS_INVALID_BAD_INTERFACE;
858 
859  if (_dbus_string_equal_substring (&_dbus_local_interface_str,
860  0,
861  _dbus_string_get_length (&_dbus_local_interface_str),
862  value_str, str_data_pos))
863  {
864  _dbus_verbose ("Message is on the local interface\n");
865  return DBUS_INVALID_USES_LOCAL_INTERFACE;
866  }
867  break;
868 
870  string_validation_func = _dbus_validate_member;
871  bad_string_code = DBUS_INVALID_BAD_MEMBER;
872  break;
873 
875  string_validation_func = _dbus_validate_error_name;
876  bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
877  break;
878 
880  string_validation_func = _dbus_validate_bus_name;
881  bad_string_code = DBUS_INVALID_BAD_SENDER;
882  break;
883 
885  /* OBJECT_PATH was validated generically due to its type */
886  string_validation_func = NULL;
887 
888  if (_dbus_string_equal_substring (&_dbus_local_path_str,
889  0,
890  _dbus_string_get_length (&_dbus_local_path_str),
891  value_str, str_data_pos))
892  {
893  _dbus_verbose ("Message is from the local path\n");
894  return DBUS_INVALID_USES_LOCAL_PATH;
895  }
896  break;
897 
899  /* Can't be 0 */
900  if (v_UINT32 == 0)
901  {
902  return DBUS_INVALID_BAD_SERIAL;
903  }
904  break;
905 
907  /* Every value makes sense */
908  break;
909 
911  /* SIGNATURE validated generically due to its type */
912  string_validation_func = NULL;
913  break;
914 
915  default:
916  _dbus_assert_not_reached ("unknown field shouldn't be seen here");
917  break;
918  }
919 
920  if (string_validation_func)
921  {
922  dbus_uint32_t len;
923 
924  _dbus_assert (bad_string_code != DBUS_VALID);
925 
926  len = _dbus_marshal_read_uint32 (value_str, value_pos,
928  NULL);
929 
930 #if 0
931  _dbus_verbose ("Validating string header field; code %d if fails\n",
932  bad_string_code);
933 #endif
934  if (!(*string_validation_func) (value_str, str_data_pos, len))
935  return bad_string_code;
936  }
937 
938  return DBUS_VALID;
939 }
940 
969  DBusValidationMode mode,
970  DBusValidity *validity,
971  int byte_order,
972  int fields_array_len,
973  int header_len,
974  int body_len,
975  const DBusString *str,
976  int start,
977  int len)
978 {
979  int leftover;
980  DBusValidity v;
981  DBusTypeReader reader;
982  DBusTypeReader array_reader;
983  unsigned char v_byte;
984  dbus_uint32_t v_uint32;
985  dbus_uint32_t serial;
986  int padding_start;
987  int padding_len;
988  int i;
989 
990  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
991  _dbus_assert (header_len <= len);
992  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
993 
994  if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
995  {
996  _dbus_verbose ("Failed to copy buffer into new header\n");
998  return FALSE;
999  }
1000 
1001  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1002  {
1003  leftover = len - header_len - body_len - start;
1004  }
1005  else
1006  {
1007  v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
1008  byte_order,
1009  &leftover,
1010  str, start, len);
1011 
1012  if (v != DBUS_VALID)
1013  {
1014  *validity = v;
1015  goto invalid;
1016  }
1017  }
1018 
1019  _dbus_assert (leftover < len);
1020 
1021  padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
1022  padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
1023  _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
1024  _dbus_assert (start + header_len == padding_start + padding_len);
1025 
1026  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1027  {
1028  if (!_dbus_string_validate_nul (str, padding_start, padding_len))
1029  {
1030  *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1031  goto invalid;
1032  }
1033  }
1034 
1035  header->padding = padding_len;
1036 
1037  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1038  {
1039  *validity = DBUS_VALID;
1040  return TRUE;
1041  }
1042 
1043  /* We now know the data is well-formed, but we have to check that
1044  * it's valid.
1045  */
1046 
1047  _dbus_type_reader_init (&reader,
1048  byte_order,
1049  &_dbus_header_signature_str, 0,
1050  str, start);
1051 
1052  /* BYTE ORDER */
1055  _dbus_type_reader_read_basic (&reader, &v_byte);
1056  _dbus_type_reader_next (&reader);
1057 
1058  _dbus_assert (v_byte == byte_order);
1059 
1060  /* MESSAGE TYPE */
1063  _dbus_type_reader_read_basic (&reader, &v_byte);
1064  _dbus_type_reader_next (&reader);
1065 
1066  /* unknown message types are supposed to be ignored, so only validation here is
1067  * that it isn't invalid
1068  */
1069  if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1070  {
1071  *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1072  goto invalid;
1073  }
1074 
1075  /* FLAGS */
1078  _dbus_type_reader_read_basic (&reader, &v_byte);
1079  _dbus_type_reader_next (&reader);
1080 
1081  /* unknown flags should be ignored */
1082 
1083  /* PROTOCOL VERSION */
1086  _dbus_type_reader_read_basic (&reader, &v_byte);
1087  _dbus_type_reader_next (&reader);
1088 
1089  if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1090  {
1091  *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1092  goto invalid;
1093  }
1094 
1095  /* BODY LENGTH */
1098  _dbus_type_reader_read_basic (&reader, &v_uint32);
1099  _dbus_type_reader_next (&reader);
1100 
1101  _dbus_assert (body_len == (signed) v_uint32);
1102 
1103  /* SERIAL */
1106  _dbus_type_reader_read_basic (&reader, &serial);
1107  _dbus_type_reader_next (&reader);
1108 
1109  if (serial == 0)
1110  {
1111  *validity = DBUS_INVALID_BAD_SERIAL;
1112  goto invalid;
1113  }
1114 
1117 
1118  _dbus_type_reader_recurse (&reader, &array_reader);
1119  while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1120  {
1121  DBusTypeReader struct_reader;
1122  DBusTypeReader variant_reader;
1123  unsigned char field_code;
1124 
1126 
1127  _dbus_type_reader_recurse (&array_reader, &struct_reader);
1128 
1130  _dbus_type_reader_read_basic (&struct_reader, &field_code);
1131  _dbus_type_reader_next (&struct_reader);
1132 
1133  if (field_code == DBUS_HEADER_FIELD_INVALID)
1134  {
1135  _dbus_verbose ("invalid header field code\n");
1136  *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1137  goto invalid;
1138  }
1139 
1140  if (field_code > DBUS_HEADER_FIELD_LAST)
1141  {
1142  _dbus_verbose ("unknown header field code %d, skipping\n",
1143  field_code);
1144  goto next_field;
1145  }
1146 
1148  _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1149 
1150  v = load_and_validate_field (header, field_code, &variant_reader);
1151  if (v != DBUS_VALID)
1152  {
1153  _dbus_verbose ("Field %d was invalid\n", field_code);
1154  *validity = v;
1155  goto invalid;
1156  }
1157 
1158  next_field:
1159  _dbus_type_reader_next (&array_reader);
1160  }
1161 
1162  /* Anything we didn't fill in is now known not to exist */
1163  i = 0;
1164  while (i <= DBUS_HEADER_FIELD_LAST)
1165  {
1166  if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1167  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1168  ++i;
1169  }
1170 
1171  v = check_mandatory_fields (header);
1172  if (v != DBUS_VALID)
1173  {
1174  _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1175  *validity = v;
1176  goto invalid;
1177  }
1178 
1179  *validity = DBUS_VALID;
1180  return TRUE;
1181 
1182  invalid:
1183  _dbus_string_set_length (&header->data, 0);
1184  return FALSE;
1185 }
1186 
1193 void
1195  int body_len)
1196 {
1197  _dbus_marshal_set_uint32 (&header->data,
1199  body_len,
1200  _dbus_header_get_byte_order (header));
1201 }
1202 
1216 static dbus_bool_t
1217 find_field_for_modification (DBusHeader *header,
1218  int field,
1219  DBusTypeReader *reader,
1220  DBusTypeReader *realign_root)
1221 {
1222  dbus_bool_t retval;
1223 
1224  retval = FALSE;
1225 
1226  _dbus_type_reader_init (realign_root,
1227  _dbus_header_get_byte_order (header),
1228  &_dbus_header_signature_str,
1230  &header->data,
1232 
1233  _dbus_type_reader_recurse (realign_root, reader);
1234 
1236  {
1237  DBusTypeReader sub;
1238  unsigned char field_code;
1239 
1240  _dbus_type_reader_recurse (reader, &sub);
1241 
1243  _dbus_type_reader_read_basic (&sub, &field_code);
1244 
1245  if (field_code == (unsigned) field)
1246  {
1248  retval = TRUE;
1249  goto done;
1250  }
1251 
1252  _dbus_type_reader_next (reader);
1253  }
1254 
1255  done:
1256  return retval;
1257 }
1258 
1272  int field,
1273  int type,
1274  const void *value)
1275 {
1277 
1278  if (!reserve_header_padding (header))
1279  return FALSE;
1280 
1281  /* If the field exists we set, otherwise we append */
1282  if (_dbus_header_cache_check (header, field))
1283  {
1284  DBusTypeReader reader;
1285  DBusTypeReader realign_root;
1286 
1287  if (!find_field_for_modification (header, field,
1288  &reader, &realign_root))
1289  _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1290 
1291  if (!set_basic_field (&reader, field, type, value, &realign_root))
1292  return FALSE;
1293  }
1294  else
1295  {
1296  DBusTypeWriter writer;
1297  DBusTypeWriter array;
1298 
1300  _dbus_header_get_byte_order (header),
1301  &_dbus_header_signature_str,
1303  &header->data,
1305 
1306  /* recurse into array without creating a new length, and jump to
1307  * end of array.
1308  */
1309  if (!_dbus_type_writer_append_array (&writer,
1310  &_dbus_header_signature_str,
1312  &array))
1313  _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1314 
1315  _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1316  _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1317  _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1318 
1319  if (!write_basic_field (&array,
1320  field, type, value))
1321  return FALSE;
1322 
1323  if (!_dbus_type_writer_unrecurse (&writer, &array))
1324  _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1325  }
1326 
1327  correct_header_padding (header);
1328 
1329  /* We could be smarter about this (only invalidate fields after the
1330  * one we modified, or even only if the one we modified changed
1331  * length). But this hack is a start.
1332  */
1333  _dbus_header_cache_invalidate_all (header);
1334 
1335  return TRUE;
1336 }
1337 
1350  int field,
1351  int type,
1352  void *value)
1353 {
1356  _dbus_assert (_dbus_header_field_types[field].code == field);
1357  /* in light of this you might ask why the type is passed in;
1358  * the only rationale I can think of is so the caller has
1359  * to specify its expectation and breaks if we change it
1360  */
1361  _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1362 
1363  if (!_dbus_header_cache_check (header, field))
1364  return FALSE;
1365 
1366  _dbus_assert (header->fields[field].value_pos >= 0);
1367 
1368  _dbus_marshal_read_basic (&header->data,
1369  header->fields[field].value_pos,
1370  type, value, _dbus_header_get_byte_order (header),
1371  NULL);
1372 
1373  return TRUE;
1374 }
1375 
1391  int field,
1392  const DBusString **str,
1393  int *pos)
1394 {
1395  if (!_dbus_header_cache_check (header, field))
1396  return FALSE;
1397 
1398  if (str)
1399  *str = &header->data;
1400  if (pos)
1401  *pos = header->fields[field].value_pos;
1402 
1403  return TRUE;
1404 }
1405 
1415  int field)
1416 {
1417  DBusTypeReader reader;
1418  DBusTypeReader realign_root;
1419 
1420  if (_dbus_header_cache_known_nonexistent (header, field))
1421  return TRUE; /* nothing to do */
1422 
1423  /* Scan to the field we want, delete and realign, reappend
1424  * padding. Field may turn out not to exist.
1425  */
1426  if (!find_field_for_modification (header, field,
1427  &reader, &realign_root))
1428  return TRUE; /* nothing to do */
1429 
1430  if (!reserve_header_padding (header))
1431  return FALSE;
1432 
1433  if (!_dbus_type_reader_delete (&reader,
1434  &realign_root))
1435  return FALSE;
1436 
1437  correct_header_padding (header);
1438 
1439  _dbus_header_cache_invalidate_all (header);
1440 
1441  _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1442 
1443  return TRUE;
1444 }
1445 
1454 void
1456  dbus_uint32_t flag,
1457  dbus_bool_t value)
1458 {
1459  unsigned char *flags_p;
1460 
1461  flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1);
1462 
1463  if (value)
1464  *flags_p |= flag;
1465  else
1466  *flags_p &= ~flag;
1467 }
1468 
1478  dbus_uint32_t flag)
1479 {
1480  const unsigned char *flags_p;
1481 
1482  flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1);
1483 
1484  return (*flags_p & flag) != 0;
1485 }
1486 
1493 void
1495  int new_order)
1496 {
1497  char byte_order;
1498 
1499  byte_order = _dbus_header_get_byte_order (header);
1500 
1501  if (byte_order == new_order)
1502  return;
1503 
1504  _dbus_marshal_byteswap (&_dbus_header_signature_str,
1505  0, byte_order,
1506  new_order,
1507  &header->data, 0);
1508 
1509  _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order);
1510 }
1511 
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:738
The type writer is an iterator for writing to a block of values.
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.
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:100
DBusString data
Header network data, stored separately from body so we can independently realloc it.
unsigned char _dbus_string_get_byte(const DBusString *str, int start)
Gets the byte at the given position.
Definition: dbus-string.c:540
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.
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()
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:468
#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:758
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:1280
#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_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.
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
#define BYTE_ORDER_OFFSET
Offset to byte order from start of header.
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.
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:1190
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.
int _dbus_string_get_length(const DBusString *str)
Gets the length of a string (not including nul termination).
Definition: dbus-string.c:717
dbus_bool_t _dbus_type_reader_next(DBusTypeReader *reader)
Skip to the next value on this &quot;level&quot;.
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_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:861
#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:2101
#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
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...
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:242
The type reader is an iterator for reading values from a block of values.
#define TRUE
Expands to &quot;1&quot;.
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.
void _dbus_string_set_byte(DBusString *str, int i, unsigned char byte)
Sets the value of the byte at the given position.
Definition: dbus-string.c:516
#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.
const char * _dbus_string_get_const_data_len(const DBusString *str, int start, int len)
const version of _dbus_string_get_data_len().
Definition: dbus-string.c:492
#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 &quot;int32&quot;.
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:2650
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 &quot;0&quot;.
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:780
#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:1372
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.