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