D-Bus  1.13.7
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  { DBUS_HEADER_FIELD_CONTAINER_INSTANCE, DBUS_TYPE_OBJECT_PATH }
88 };
89 
91 #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type)
92 
94 #define MAX_POSSIBLE_HEADER_PADDING 7
95 static dbus_bool_t
96 reserve_header_padding (DBusHeader *header)
97 {
99 
100  if (!_dbus_string_lengthen (&header->data,
102  return FALSE;
104  return TRUE;
105 }
106 
107 static void
108 correct_header_padding (DBusHeader *header)
109 {
110  int unpadded_len;
111 
112  _dbus_assert (header->padding == 7);
113 
114  _dbus_string_shorten (&header->data, header->padding);
115  unpadded_len = _dbus_string_get_length (&header->data);
116 
117  if (!_dbus_string_align_length (&header->data, 8))
118  _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");
119 
120  header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
121 }
122 
126 #define HEADER_END_BEFORE_PADDING(header) \
127  (_dbus_string_get_length (&(header)->data) - (header)->padding)
128 
136 static void
137 _dbus_header_cache_invalidate_all (DBusHeader *header)
138 {
139  int i;
140 
141  i = 0;
142  while (i <= DBUS_HEADER_FIELD_LAST)
143  {
144  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN;
145  ++i;
146  }
147 }
148 
156 static void
157 _dbus_header_cache_one (DBusHeader *header,
158  int field_code,
159  DBusTypeReader *variant_reader)
160 {
161  header->fields[field_code].value_pos =
162  _dbus_type_reader_get_value_pos (variant_reader);
163 
164 #if 0
165  _dbus_verbose ("cached value_pos %d for field %d\n",
166  header->fields[field_code].value_pos, field_code)
167 #endif
168 }
169 
176 char
178 {
179  _dbus_assert (_dbus_string_get_length (&header->data) > BYTE_ORDER_OFFSET);
180 
181  return (char) _dbus_string_get_byte (&header->data, BYTE_ORDER_OFFSET);
182 }
183 
189 static void
190 _dbus_header_cache_revalidate (DBusHeader *header)
191 {
192  DBusTypeReader array;
193  DBusTypeReader reader;
194  int i;
195 
196  i = 0;
197  while (i <= DBUS_HEADER_FIELD_LAST)
198  {
199  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
200  ++i;
201  }
202 
203  _dbus_type_reader_init (&reader,
205  &_dbus_header_signature_str,
207  &header->data,
209 
210  _dbus_type_reader_recurse (&reader, &array);
211 
213  {
214  DBusTypeReader sub;
215  DBusTypeReader variant;
216  unsigned char field_code;
217 
218  _dbus_type_reader_recurse (&array, &sub);
219 
221  _dbus_type_reader_read_basic (&sub, &field_code);
222 
223  /* Unknown fields should be ignored */
224  if (field_code > DBUS_HEADER_FIELD_LAST)
225  goto next_field;
226 
227  _dbus_type_reader_next (&sub);
228 
230  _dbus_type_reader_recurse (&sub, &variant);
231 
232  _dbus_header_cache_one (header, field_code, &variant);
233 
234  next_field:
235  _dbus_type_reader_next (&array);
236  }
237 }
238 
246 static dbus_bool_t
247 _dbus_header_cache_check (DBusHeader *header,
248  int field)
249 {
251 
252  if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
253  _dbus_header_cache_revalidate (header);
254 
255  if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
256  return FALSE;
257 
258  return TRUE;
259 }
260 
269 static dbus_bool_t
270 _dbus_header_cache_known_nonexistent (DBusHeader *header,
271  int field)
272 {
274 
275  return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
276 }
277 
287 static dbus_bool_t
288 write_basic_field (DBusTypeWriter *writer,
289  int field,
290  int type,
291  const void *value)
292 {
293  DBusTypeWriter sub;
294  DBusTypeWriter variant;
295  int start;
296  int padding;
297  unsigned char field_byte;
298  DBusString contained_type;
299  char buf[2];
300 
301  start = writer->value_pos;
302  padding = _dbus_string_get_length (writer->value_str) - start;
303 
305  NULL, 0, &sub))
306  goto append_failed;
307 
308  field_byte = field;
310  &field_byte))
311  goto append_failed;
312 
313  buf[0] = type;
314  buf[1] = '\0';
315  _dbus_string_init_const_len (&contained_type, buf, 1);
316 
318  &contained_type, 0, &variant))
319  goto append_failed;
320 
321  if (!_dbus_type_writer_write_basic (&variant, type, value))
322  goto append_failed;
323 
324  if (!_dbus_type_writer_unrecurse (&sub, &variant))
325  goto append_failed;
326 
327  if (!_dbus_type_writer_unrecurse (writer, &sub))
328  goto append_failed;
329 
330  return TRUE;
331 
332  append_failed:
334  start,
335  _dbus_string_get_length (writer->value_str) - start - padding);
336  return FALSE;
337 }
338 
349 static dbus_bool_t
350 set_basic_field (DBusTypeReader *reader,
351  int field,
352  int type,
353  const void *value,
354  const DBusTypeReader *realign_root)
355 {
356  DBusTypeReader sub;
357  DBusTypeReader variant;
358 
359  _dbus_type_reader_recurse (reader, &sub);
360 
362 #ifndef DBUS_DISABLE_ASSERT
363  {
364  unsigned char v_BYTE;
365  _dbus_type_reader_read_basic (&sub, &v_BYTE);
366  _dbus_assert (((int) v_BYTE) == field);
367  }
368 #endif
369 
370  if (!_dbus_type_reader_next (&sub))
371  _dbus_assert_not_reached ("no variant field?");
372 
373  _dbus_type_reader_recurse (&sub, &variant);
375 
376  if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
377  return FALSE;
378 
379  return TRUE;
380 }
381 
388 int
390 {
391  int type;
392 
393  type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
395 
396  return type;
397 }
398 
406 void
408  dbus_uint32_t serial)
409 {
410  /* we use this function to set the serial on outgoing
411  * messages, and to reset the serial in dbus_message_copy;
412  * this assertion should catch a double-set on outgoing.
413  */
414  _dbus_assert (_dbus_header_get_serial (header) == 0 ||
415  serial == 0);
416 
417  _dbus_marshal_set_uint32 (&header->data,
419  serial,
420  _dbus_header_get_byte_order (header));
421 }
422 
429 dbus_uint32_t
431 {
432  return _dbus_marshal_read_uint32 (&header->data,
435  NULL);
436 }
437 
445 void
447 {
448  _dbus_string_set_length (&header->data, 0);
449 
450  header->padding = 0;
451 
452  _dbus_header_cache_invalidate_all (header);
453 }
454 
464 {
465  if (!_dbus_string_init_preallocated (&header->data, 32))
466  return FALSE;
467 
468  _dbus_header_reinit (header);
469 
470  return TRUE;
471 }
472 
478 void
480 {
481  _dbus_string_free (&header->data);
482 }
483 
494  DBusHeader *dest)
495 {
496  *dest = *header;
497 
499  _dbus_string_get_length (&header->data)))
500  return FALSE;
501 
502  if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
503  {
504  _dbus_string_free (&dest->data);
505  return FALSE;
506  }
507 
508  /* Reset the serial */
509  _dbus_header_set_serial (dest, 0);
510 
511  return TRUE;
512 }
513 
532  int byte_order,
533  int message_type,
534  const char *destination,
535  const char *path,
536  const char *interface,
537  const char *member,
538  const char *error_name)
539 {
540  unsigned char v_BYTE;
541  dbus_uint32_t v_UINT32;
542  DBusTypeWriter writer;
543  DBusTypeWriter array;
544 
545  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
546  byte_order == DBUS_BIG_ENDIAN);
547  _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
548  (error_name) ||
549  !(interface || member || error_name));
550  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
551 
552  if (!reserve_header_padding (header))
553  return FALSE;
554 
555  _dbus_type_writer_init_values_only (&writer, byte_order,
556  &_dbus_header_signature_str, 0,
557  &header->data,
558  HEADER_END_BEFORE_PADDING (header));
559 
560  v_BYTE = byte_order;
562  &v_BYTE))
563  goto oom;
564 
565  v_BYTE = message_type;
567  &v_BYTE))
568  goto oom;
569 
570  v_BYTE = 0; /* flags */
572  &v_BYTE))
573  goto oom;
574 
577  &v_BYTE))
578  goto oom;
579 
580  v_UINT32 = 0; /* body length */
582  &v_UINT32))
583  goto oom;
584 
585  v_UINT32 = 0; /* serial */
587  &v_UINT32))
588  goto oom;
589 
591  &_dbus_header_signature_str,
593  &array))
594  goto oom;
595 
596  /* Marshal all the fields (Marshall Fields?) */
597 
598  if (path != NULL)
599  {
600  if (!write_basic_field (&array,
603  &path))
604  goto oom;
605  }
606 
607  if (destination != NULL)
608  {
609  if (!write_basic_field (&array,
612  &destination))
613  goto oom;
614  }
615 
616  /* Note that test/message.c relies on this being in the middle of the
617  * message: if you change the order of serialization here (but why
618  * would you?), please find some other way to retain test coverage. */
619  if (interface != NULL)
620  {
621  if (!write_basic_field (&array,
624  &interface))
625  goto oom;
626  }
627 
628  if (member != NULL)
629  {
630  if (!write_basic_field (&array,
633  &member))
634  goto oom;
635  }
636 
637  if (error_name != NULL)
638  {
639  if (!write_basic_field (&array,
642  &error_name))
643  goto oom;
644  }
645 
646  if (!_dbus_type_writer_unrecurse (&writer, &array))
647  goto oom;
648 
649  correct_header_padding (header);
650 
651  return TRUE;
652 
653  oom:
654  _dbus_string_delete (&header->data, 0,
655  _dbus_string_get_length (&header->data) - header->padding);
656  correct_header_padding (header);
657 
658  return FALSE;
659 }
660 
679 _dbus_header_have_message_untrusted (int max_message_length,
680  DBusValidity *validity,
681  int *byte_order,
682  int *fields_array_len,
683  int *header_len,
684  int *body_len,
685  const DBusString *str,
686  int start,
687  int len)
688 
689 {
690  dbus_uint32_t header_len_unsigned;
691  dbus_uint32_t fields_array_len_unsigned;
692  dbus_uint32_t body_len_unsigned;
693 
694  _dbus_assert (start >= 0);
695  _dbus_assert (start < _DBUS_INT32_MAX / 2);
696  _dbus_assert (len >= 0);
697 
698  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
699 
700  *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
701 
702  if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
703  {
704  *validity = DBUS_INVALID_BAD_BYTE_ORDER;
705  return FALSE;
706  }
707 
709  fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
710  *byte_order, NULL);
711 
712  if (fields_array_len_unsigned > (unsigned) max_message_length)
713  {
714  *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
715  return FALSE;
716  }
717 
718  _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
719  body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
720  *byte_order, NULL);
721 
722  if (body_len_unsigned > (unsigned) max_message_length)
723  {
724  *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
725  return FALSE;
726  }
727 
728  header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
729  header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
730 
731  /* overflow should be impossible since the lengths aren't allowed to
732  * be huge.
733  */
734  _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2);
735  if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
736  {
737  *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
738  return FALSE;
739  }
740 
741  _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX);
742  _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX);
743  _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX);
744 
745  *body_len = body_len_unsigned;
746  *fields_array_len = fields_array_len_unsigned;
747  *header_len = header_len_unsigned;
748 
749  *validity = DBUS_VALID;
750 
751  _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
752  len, body_len_unsigned, header_len_unsigned,
753  body_len_unsigned + header_len_unsigned);
754 
755  return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
756 }
757 
758 static DBusValidity
759 check_mandatory_fields (DBusHeader *header)
760 {
761 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
762 
763  switch (_dbus_header_get_message_type (header))
764  {
766  REQUIRE_FIELD (INTERFACE);
767  /* FALL THRU - signals also require the path and member */
769  REQUIRE_FIELD (PATH);
770  REQUIRE_FIELD (MEMBER);
771  break;
773  REQUIRE_FIELD (ERROR_NAME);
774  REQUIRE_FIELD (REPLY_SERIAL);
775  break;
777  REQUIRE_FIELD (REPLY_SERIAL);
778  break;
779  default:
780  /* other message types allowed but ignored */
781  break;
782  }
783 
784  return DBUS_VALID;
785 }
786 
787 static DBusValidity
788 load_and_validate_field (DBusHeader *header,
789  int field,
790  DBusTypeReader *variant_reader)
791 {
792  int type;
793  int expected_type;
794  const DBusString *value_str;
795  int value_pos;
796  int str_data_pos;
797  dbus_uint32_t v_UINT32;
798  int bad_string_code;
799  dbus_bool_t (* string_validation_func) (const DBusString *str,
800  int start, int len);
801 
802  /* Supposed to have been checked already */
805 
806  /* Before we can cache a field, we need to know it has the right type */
807  type = _dbus_type_reader_get_current_type (variant_reader);
808 
809  _dbus_assert (_dbus_header_field_types[field].code == field);
810 
811  expected_type = EXPECTED_TYPE_OF_FIELD (field);
812  if (type != expected_type)
813  {
814  _dbus_verbose ("Field %d should have type %d but has %d\n",
815  field, expected_type, type);
816  return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
817  }
818 
819  /* If the field was provided twice, we aren't happy */
820  if (header->fields[field].value_pos >= 0)
821  {
822  _dbus_verbose ("Header field %d seen a second time\n", field);
823  return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
824  }
825 
826  /* Now we can cache and look at the field content */
827  _dbus_verbose ("initially caching field %d\n", field);
828  _dbus_header_cache_one (header, field, variant_reader);
829 
830  string_validation_func = NULL;
831 
832  /* make compiler happy that all this is initialized */
833  v_UINT32 = 0;
834  value_str = NULL;
835  value_pos = -1;
836  str_data_pos = -1;
837  bad_string_code = DBUS_VALID;
838 
839  if (expected_type == DBUS_TYPE_UINT32)
840  {
841  _dbus_header_get_field_basic (header, field, expected_type,
842  &v_UINT32);
843  }
844  else if (expected_type == DBUS_TYPE_STRING ||
845  expected_type == DBUS_TYPE_OBJECT_PATH ||
846  expected_type == DBUS_TYPE_SIGNATURE)
847  {
848  _dbus_header_get_field_raw (header, field,
849  &value_str, &value_pos);
850  str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
851  }
852  else
853  {
854  _dbus_assert_not_reached ("none of the known fields should have this type");
855  }
856 
857  switch (field)
858  {
860  string_validation_func = _dbus_validate_bus_name;
861  bad_string_code = DBUS_INVALID_BAD_DESTINATION;
862  break;
864  string_validation_func = _dbus_validate_interface;
865  bad_string_code = DBUS_INVALID_BAD_INTERFACE;
866 
867  if (_dbus_string_equal_substring (&_dbus_local_interface_str,
868  0,
869  _dbus_string_get_length (&_dbus_local_interface_str),
870  value_str, str_data_pos))
871  {
872  _dbus_verbose ("Message is on the local interface\n");
873  return DBUS_INVALID_USES_LOCAL_INTERFACE;
874  }
875  break;
876 
878  string_validation_func = _dbus_validate_member;
879  bad_string_code = DBUS_INVALID_BAD_MEMBER;
880  break;
881 
883  string_validation_func = _dbus_validate_error_name;
884  bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
885  break;
886 
888  string_validation_func = _dbus_validate_bus_name;
889  bad_string_code = DBUS_INVALID_BAD_SENDER;
890  break;
891 
893  /* OBJECT_PATH was validated generically due to its type */
894  string_validation_func = NULL;
895 
896  if (_dbus_string_equal_substring (&_dbus_local_path_str,
897  0,
898  _dbus_string_get_length (&_dbus_local_path_str),
899  value_str, str_data_pos))
900  {
901  _dbus_verbose ("Message is from the local path\n");
902  return DBUS_INVALID_USES_LOCAL_PATH;
903  }
904  break;
905 
907  /* Can't be 0 */
908  if (v_UINT32 == 0)
909  {
910  return DBUS_INVALID_BAD_SERIAL;
911  }
912  break;
913 
915  /* Every value makes sense */
916  break;
917 
919  /* SIGNATURE validated generically due to its type */
920  string_validation_func = NULL;
921  break;
922 
924  /* OBJECT_PATH was validated generically due to its type */
925  string_validation_func = NULL;
926  break;
927 
928  default:
929  _dbus_assert_not_reached ("unknown field shouldn't be seen here");
930  break;
931  }
932 
933  if (string_validation_func)
934  {
935  dbus_uint32_t len;
936 
937  _dbus_assert (bad_string_code != DBUS_VALID);
938 
939  len = _dbus_marshal_read_uint32 (value_str, value_pos,
941  NULL);
942 
943 #if 0
944  _dbus_verbose ("Validating string header field; code %d if fails\n",
945  bad_string_code);
946 #endif
947  if (!(*string_validation_func) (value_str, str_data_pos, len))
948  return bad_string_code;
949  }
950 
951  return DBUS_VALID;
952 }
953 
980  DBusValidationMode mode,
981  DBusValidity *validity,
982  int byte_order,
983  int fields_array_len,
984  int header_len,
985  int body_len,
986  const DBusString *str)
987 {
988  int leftover;
989  DBusValidity v;
990  DBusTypeReader reader;
991  DBusTypeReader array_reader;
992  unsigned char v_byte;
993  dbus_uint32_t v_uint32;
994  dbus_uint32_t serial;
995  int padding_start;
996  int padding_len;
997  int i;
998  int len;
999 
1000  len = _dbus_string_get_length (str);
1001 
1002  _dbus_assert (header_len <= len);
1003  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
1004 
1005  if (!_dbus_string_copy_len (str, 0, header_len, &header->data, 0))
1006  {
1007  _dbus_verbose ("Failed to copy buffer into new header\n");
1008  *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
1009  return FALSE;
1010  }
1011 
1012  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1013  {
1014  leftover = len - header_len - body_len;
1015  }
1016  else
1017  {
1018  v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
1019  byte_order,
1020  &leftover,
1021  str, 0, len);
1022 
1023  if (v != DBUS_VALID)
1024  {
1025  *validity = v;
1026  goto invalid;
1027  }
1028  }
1029 
1030  _dbus_assert (leftover < len);
1031 
1032  padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
1033  padding_start = FIRST_FIELD_OFFSET + fields_array_len;
1034  _dbus_assert (header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
1035  _dbus_assert (header_len == padding_start + padding_len);
1036 
1037  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1038  {
1039  if (!_dbus_string_validate_nul (str, padding_start, padding_len))
1040  {
1041  *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1042  goto invalid;
1043  }
1044  }
1045 
1046  header->padding = padding_len;
1047 
1048  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1049  {
1050  *validity = DBUS_VALID;
1051  return TRUE;
1052  }
1053 
1054  /* We now know the data is well-formed, but we have to check that
1055  * it's valid.
1056  */
1057 
1058  _dbus_type_reader_init (&reader,
1059  byte_order,
1060  &_dbus_header_signature_str, 0,
1061  str, 0);
1062 
1063  /* BYTE ORDER */
1066  _dbus_type_reader_read_basic (&reader, &v_byte);
1067  _dbus_type_reader_next (&reader);
1068 
1069  _dbus_assert (v_byte == byte_order);
1070 
1071  /* MESSAGE TYPE */
1074  _dbus_type_reader_read_basic (&reader, &v_byte);
1075  _dbus_type_reader_next (&reader);
1076 
1077  /* unknown message types are supposed to be ignored, so only validation here is
1078  * that it isn't invalid
1079  */
1080  if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1081  {
1082  *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1083  goto invalid;
1084  }
1085 
1086  /* FLAGS */
1089  _dbus_type_reader_read_basic (&reader, &v_byte);
1090  _dbus_type_reader_next (&reader);
1091 
1092  /* unknown flags should be ignored */
1093 
1094  /* PROTOCOL VERSION */
1097  _dbus_type_reader_read_basic (&reader, &v_byte);
1098  _dbus_type_reader_next (&reader);
1099 
1100  if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1101  {
1102  *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1103  goto invalid;
1104  }
1105 
1106  /* BODY LENGTH */
1109  _dbus_type_reader_read_basic (&reader, &v_uint32);
1110  _dbus_type_reader_next (&reader);
1111 
1112  _dbus_assert (body_len == (signed) v_uint32);
1113 
1114  /* SERIAL */
1117  _dbus_type_reader_read_basic (&reader, &serial);
1118  _dbus_type_reader_next (&reader);
1119 
1120  if (serial == 0)
1121  {
1122  *validity = DBUS_INVALID_BAD_SERIAL;
1123  goto invalid;
1124  }
1125 
1128 
1129  _dbus_type_reader_recurse (&reader, &array_reader);
1130  while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1131  {
1132  DBusTypeReader struct_reader;
1133  DBusTypeReader variant_reader;
1134  unsigned char field_code;
1135 
1137 
1138  _dbus_type_reader_recurse (&array_reader, &struct_reader);
1139 
1141  _dbus_type_reader_read_basic (&struct_reader, &field_code);
1142  _dbus_type_reader_next (&struct_reader);
1143 
1144  if (field_code == DBUS_HEADER_FIELD_INVALID)
1145  {
1146  _dbus_verbose ("invalid header field code\n");
1147  *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1148  goto invalid;
1149  }
1150 
1151  if (field_code > DBUS_HEADER_FIELD_LAST)
1152  {
1153  _dbus_verbose ("unknown header field code %d, skipping\n",
1154  field_code);
1155  goto next_field;
1156  }
1157 
1159  _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1160 
1161  v = load_and_validate_field (header, field_code, &variant_reader);
1162  if (v != DBUS_VALID)
1163  {
1164  _dbus_verbose ("Field %d was invalid\n", field_code);
1165  *validity = v;
1166  goto invalid;
1167  }
1168 
1169  next_field:
1170  _dbus_type_reader_next (&array_reader);
1171  }
1172 
1173  /* Anything we didn't fill in is now known not to exist */
1174  i = 0;
1175  while (i <= DBUS_HEADER_FIELD_LAST)
1176  {
1177  if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1178  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1179  ++i;
1180  }
1181 
1182  v = check_mandatory_fields (header);
1183  if (v != DBUS_VALID)
1184  {
1185  _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1186  *validity = v;
1187  goto invalid;
1188  }
1189 
1190  *validity = DBUS_VALID;
1191  return TRUE;
1192 
1193  invalid:
1194  _dbus_string_set_length (&header->data, 0);
1195  return FALSE;
1196 }
1197 
1204 void
1206  int body_len)
1207 {
1208  _dbus_marshal_set_uint32 (&header->data,
1210  body_len,
1211  _dbus_header_get_byte_order (header));
1212 }
1213 
1227 static dbus_bool_t
1228 find_field_for_modification (DBusHeader *header,
1229  int field,
1230  DBusTypeReader *reader,
1231  DBusTypeReader *realign_root)
1232 {
1233  dbus_bool_t retval;
1234 
1235  retval = FALSE;
1236 
1237  _dbus_type_reader_init (realign_root,
1238  _dbus_header_get_byte_order (header),
1239  &_dbus_header_signature_str,
1241  &header->data,
1243 
1244  _dbus_type_reader_recurse (realign_root, reader);
1245 
1247  {
1248  DBusTypeReader sub;
1249  unsigned char field_code;
1250 
1251  _dbus_type_reader_recurse (reader, &sub);
1252 
1254  _dbus_type_reader_read_basic (&sub, &field_code);
1255 
1256  if (field_code == (unsigned) field)
1257  {
1259  retval = TRUE;
1260  goto done;
1261  }
1262 
1263  _dbus_type_reader_next (reader);
1264  }
1265 
1266  done:
1267  return retval;
1268 }
1269 
1283  int field,
1284  int type,
1285  const void *value)
1286 {
1288 
1289  if (!reserve_header_padding (header))
1290  return FALSE;
1291 
1292  /* If the field exists we set, otherwise we append */
1293  if (_dbus_header_cache_check (header, field))
1294  {
1295  DBusTypeReader reader;
1296  DBusTypeReader realign_root;
1297 
1298  if (!find_field_for_modification (header, field,
1299  &reader, &realign_root))
1300  _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1301 
1302  if (!set_basic_field (&reader, field, type, value, &realign_root))
1303  return FALSE;
1304  }
1305  else
1306  {
1307  DBusTypeWriter writer;
1308  DBusTypeWriter array;
1309 
1311  _dbus_header_get_byte_order (header),
1312  &_dbus_header_signature_str,
1314  &header->data,
1316 
1317  /* recurse into array without creating a new length, and jump to
1318  * end of array.
1319  */
1320  if (!_dbus_type_writer_append_array (&writer,
1321  &_dbus_header_signature_str,
1323  &array))
1324  _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1325 
1326  _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1327  _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1328  _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1329 
1330  if (!write_basic_field (&array,
1331  field, type, value))
1332  return FALSE;
1333 
1334  if (!_dbus_type_writer_unrecurse (&writer, &array))
1335  _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1336  }
1337 
1338  correct_header_padding (header);
1339 
1340  /* We could be smarter about this (only invalidate fields after the
1341  * one we modified, or even only if the one we modified changed
1342  * length). But this hack is a start.
1343  */
1344  _dbus_header_cache_invalidate_all (header);
1345 
1346  return TRUE;
1347 }
1348 
1361  int field,
1362  int type,
1363  void *value)
1364 {
1367  _dbus_assert (_dbus_header_field_types[field].code == field);
1368  /* in light of this you might ask why the type is passed in;
1369  * the only rationale I can think of is so the caller has
1370  * to specify its expectation and breaks if we change it
1371  */
1372  _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1373 
1374  if (!_dbus_header_cache_check (header, field))
1375  return FALSE;
1376 
1377  _dbus_assert (header->fields[field].value_pos >= 0);
1378 
1379  _dbus_marshal_read_basic (&header->data,
1380  header->fields[field].value_pos,
1381  type, value, _dbus_header_get_byte_order (header),
1382  NULL);
1383 
1384  return TRUE;
1385 }
1386 
1402  int field,
1403  const DBusString **str,
1404  int *pos)
1405 {
1406  if (!_dbus_header_cache_check (header, field))
1407  return FALSE;
1408 
1409  if (str)
1410  *str = &header->data;
1411  if (pos)
1412  *pos = header->fields[field].value_pos;
1413 
1414  return TRUE;
1415 }
1416 
1426  int field)
1427 {
1428  DBusTypeReader reader;
1429  DBusTypeReader realign_root;
1430 
1431  if (_dbus_header_cache_known_nonexistent (header, field))
1432  return TRUE; /* nothing to do */
1433 
1434  /* Scan to the field we want, delete and realign, reappend
1435  * padding. Field may turn out not to exist.
1436  */
1437  if (!find_field_for_modification (header, field,
1438  &reader, &realign_root))
1439  return TRUE; /* nothing to do */
1440 
1441  if (!reserve_header_padding (header))
1442  return FALSE;
1443 
1444  if (!_dbus_type_reader_delete (&reader,
1445  &realign_root))
1446  return FALSE;
1447 
1448  correct_header_padding (header);
1449 
1450  _dbus_header_cache_invalidate_all (header);
1451 
1452  _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1453 
1454  return TRUE;
1455 }
1456 
1465 void
1467  dbus_uint32_t flag,
1468  dbus_bool_t value)
1469 {
1470  unsigned char *flags_p;
1471 
1472  flags_p = _dbus_string_get_udata_len (&header->data, FLAGS_OFFSET, 1);
1473 
1474  if (value)
1475  *flags_p |= flag;
1476  else
1477  *flags_p &= ~flag;
1478 }
1479 
1489  dbus_uint32_t flag)
1490 {
1491  const unsigned char *flags_p;
1492 
1493  flags_p = _dbus_string_get_const_udata_len (&header->data, FLAGS_OFFSET, 1);
1494 
1495  return (*flags_p & flag) != 0;
1496 }
1497 
1504 void
1506  int new_order)
1507 {
1508  char byte_order;
1509 
1510  byte_order = _dbus_header_get_byte_order (header);
1511 
1512  if (byte_order == new_order)
1513  return;
1514 
1515  _dbus_marshal_byteswap (&_dbus_header_signature_str,
1516  0, byte_order,
1517  new_order,
1518  &header->data, 0);
1519 
1520  _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order);
1521 }
1522 
1531 {
1532  DBusTypeReader array;
1533  DBusTypeReader fields_reader;
1534 
1535  _dbus_type_reader_init (&fields_reader,
1536  _dbus_header_get_byte_order (header),
1537  &_dbus_header_signature_str,
1539  &header->data,
1541 
1542  _dbus_type_reader_recurse (&fields_reader, &array);
1543 
1545  {
1546  DBusTypeReader sub;
1547  unsigned char field_code;
1548 
1549  _dbus_type_reader_recurse (&array, &sub);
1550 
1552  _dbus_type_reader_read_basic (&sub, &field_code);
1553 
1554  if (field_code > DBUS_HEADER_FIELD_LAST)
1555  {
1556  if (!reserve_header_padding (header))
1557  return FALSE;
1558 
1559  if (!_dbus_type_reader_delete (&array, &fields_reader))
1560  return FALSE;
1561 
1562  correct_header_padding (header);
1563  _dbus_header_cache_invalidate_all (header);
1564  }
1565  else
1566  {
1567  _dbus_type_reader_next (&array);
1568  }
1569  }
1570 
1571  return TRUE;
1572 }
1573 
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_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:777
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.
dbus_bool_t _dbus_header_remove_unknown_fields(DBusHeader *header)
Remove every header field not known to this version of dbus.
#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
0-7 bytes of alignment in header, the distance from [B] to [C]
#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:107
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 DBUS_HEADER_FIELD_CONTAINER_INSTANCE
Header field code for the container instance that sent this message.
#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:797
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:1300
#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_header_load(DBusHeader *header, DBusValidationMode mode, DBusValidity *validity, int byte_order, int fields_array_len, int header_len, int body_len, const DBusString *str)
Creates a message header from potentially-untrusted data.
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:1210
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:900
#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:2121
#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(), and fills it with the same contents as #_DBUS_STRING_I...
Definition: dbus-string.c:264
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:2670
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:819
#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:1392
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.