D-Bus  1.4.10
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 
172 static void
173 _dbus_header_cache_revalidate (DBusHeader *header)
174 {
175  DBusTypeReader array;
176  DBusTypeReader reader;
177  int i;
178 
179  i = 0;
180  while (i <= DBUS_HEADER_FIELD_LAST)
181  {
182  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
183  ++i;
184  }
185 
186  _dbus_type_reader_init (&reader,
187  header->byte_order,
188  &_dbus_header_signature_str,
190  &header->data,
192 
193  _dbus_type_reader_recurse (&reader, &array);
194 
196  {
197  DBusTypeReader sub;
198  DBusTypeReader variant;
199  unsigned char field_code;
200 
201  _dbus_type_reader_recurse (&array, &sub);
202 
204  _dbus_type_reader_read_basic (&sub, &field_code);
205 
206  /* Unknown fields should be ignored */
207  if (field_code > DBUS_HEADER_FIELD_LAST)
208  goto next_field;
209 
210  _dbus_type_reader_next (&sub);
211 
213  _dbus_type_reader_recurse (&sub, &variant);
214 
215  _dbus_header_cache_one (header, field_code, &variant);
216 
217  next_field:
218  _dbus_type_reader_next (&array);
219  }
220 }
221 
229 static dbus_bool_t
230 _dbus_header_cache_check (DBusHeader *header,
231  int field)
232 {
234 
235  if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
236  _dbus_header_cache_revalidate (header);
237 
238  if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
239  return FALSE;
240 
241  return TRUE;
242 }
243 
252 static dbus_bool_t
253 _dbus_header_cache_known_nonexistent (DBusHeader *header,
254  int field)
255 {
257 
258  return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
259 }
260 
269 static dbus_bool_t
270 write_basic_field (DBusTypeWriter *writer,
271  int field,
272  int type,
273  const void *value)
274 {
275  DBusTypeWriter sub;
276  DBusTypeWriter variant;
277  int start;
278  int padding;
279  unsigned char field_byte;
280  DBusString contained_type;
281  char buf[2];
282 
283  start = writer->value_pos;
284  padding = _dbus_string_get_length (writer->value_str) - start;
285 
287  NULL, 0, &sub))
288  goto append_failed;
289 
290  field_byte = field;
292  &field_byte))
293  goto append_failed;
294 
295  buf[0] = type;
296  buf[1] = '\0';
297  _dbus_string_init_const_len (&contained_type, buf, 1);
298 
300  &contained_type, 0, &variant))
301  goto append_failed;
302 
303  if (!_dbus_type_writer_write_basic (&variant, type, value))
304  goto append_failed;
305 
306  if (!_dbus_type_writer_unrecurse (&sub, &variant))
307  goto append_failed;
308 
309  if (!_dbus_type_writer_unrecurse (writer, &sub))
310  goto append_failed;
311 
312  return TRUE;
313 
314  append_failed:
316  start,
317  _dbus_string_get_length (writer->value_str) - start - padding);
318  return FALSE;
319 }
320 
330 static dbus_bool_t
331 set_basic_field (DBusTypeReader *reader,
332  int field,
333  int type,
334  const void *value,
335  const DBusTypeReader *realign_root)
336 {
337  DBusTypeReader sub;
338  DBusTypeReader variant;
339 
340  _dbus_type_reader_recurse (reader, &sub);
341 
343 #ifndef DBUS_DISABLE_ASSERT
344  {
345  unsigned char v_BYTE;
346  _dbus_type_reader_read_basic (&sub, &v_BYTE);
347  _dbus_assert (((int) v_BYTE) == field);
348  }
349 #endif
350 
351  if (!_dbus_type_reader_next (&sub))
352  _dbus_assert_not_reached ("no variant field?");
353 
354  _dbus_type_reader_recurse (&sub, &variant);
356 
357  if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
358  return FALSE;
359 
360  return TRUE;
361 }
362 
369 int
371 {
372  int type;
373 
374  type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
376 
377  return type;
378 }
379 
387 void
389  dbus_uint32_t serial)
390 {
391  /* we use this function to set the serial on outgoing
392  * messages, and to reset the serial in dbus_message_copy;
393  * this assertion should catch a double-set on outgoing.
394  */
395  _dbus_assert (_dbus_header_get_serial (header) == 0 ||
396  serial == 0);
397 
398  _dbus_marshal_set_uint32 (&header->data,
400  serial,
401  header->byte_order);
402 }
403 
412 {
413  return _dbus_marshal_read_uint32 (&header->data,
415  header->byte_order,
416  NULL);
417 }
418 
427 void
429  int byte_order)
430 {
431  _dbus_string_set_length (&header->data, 0);
432 
433  header->byte_order = byte_order;
434  header->padding = 0;
435 
436  _dbus_header_cache_invalidate_all (header);
437 }
438 
449  int byte_order)
450 {
451  if (!_dbus_string_init_preallocated (&header->data, 32))
452  return FALSE;
453 
454  _dbus_header_reinit (header, byte_order);
455 
456  return TRUE;
457 }
458 
464 void
466 {
467  _dbus_string_free (&header->data);
468 }
469 
480  DBusHeader *dest)
481 {
482  *dest = *header;
483 
485  _dbus_string_get_length (&header->data)))
486  return FALSE;
487 
488  if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
489  {
490  _dbus_string_free (&dest->data);
491  return FALSE;
492  }
493 
494  /* Reset the serial */
495  _dbus_header_set_serial (dest, 0);
496 
497  return TRUE;
498 }
499 
517  int message_type,
518  const char *destination,
519  const char *path,
520  const char *interface,
521  const char *member,
522  const char *error_name)
523 {
524  unsigned char v_BYTE;
525  dbus_uint32_t v_UINT32;
526  DBusTypeWriter writer;
527  DBusTypeWriter array;
528 
529  _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
530  (error_name) ||
531  !(interface || member || error_name));
532  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
533 
534  if (!reserve_header_padding (header))
535  return FALSE;
536 
538  &_dbus_header_signature_str, 0,
539  &header->data,
540  HEADER_END_BEFORE_PADDING (header));
541 
542  v_BYTE = header->byte_order;
544  &v_BYTE))
545  goto oom;
546 
547  v_BYTE = message_type;
549  &v_BYTE))
550  goto oom;
551 
552  v_BYTE = 0; /* flags */
554  &v_BYTE))
555  goto oom;
556 
559  &v_BYTE))
560  goto oom;
561 
562  v_UINT32 = 0; /* body length */
564  &v_UINT32))
565  goto oom;
566 
567  v_UINT32 = 0; /* serial */
569  &v_UINT32))
570  goto oom;
571 
573  &_dbus_header_signature_str,
575  &array))
576  goto oom;
577 
578  /* Marshal all the fields (Marshall Fields?) */
579 
580  if (path != NULL)
581  {
582  if (!write_basic_field (&array,
585  &path))
586  goto oom;
587  }
588 
589  if (destination != NULL)
590  {
591  if (!write_basic_field (&array,
594  &destination))
595  goto oom;
596  }
597 
598  if (interface != NULL)
599  {
600  if (!write_basic_field (&array,
603  &interface))
604  goto oom;
605  }
606 
607  if (member != NULL)
608  {
609  if (!write_basic_field (&array,
612  &member))
613  goto oom;
614  }
615 
616  if (error_name != NULL)
617  {
618  if (!write_basic_field (&array,
621  &error_name))
622  goto oom;
623  }
624 
625  if (!_dbus_type_writer_unrecurse (&writer, &array))
626  goto oom;
627 
628  correct_header_padding (header);
629 
630  return TRUE;
631 
632  oom:
633  _dbus_string_delete (&header->data, 0,
634  _dbus_string_get_length (&header->data) - header->padding);
635  correct_header_padding (header);
636 
637  return FALSE;
638 }
639 
658 _dbus_header_have_message_untrusted (int max_message_length,
659  DBusValidity *validity,
660  int *byte_order,
661  int *fields_array_len,
662  int *header_len,
663  int *body_len,
664  const DBusString *str,
665  int start,
666  int len)
667 
668 {
669  dbus_uint32_t header_len_unsigned;
670  dbus_uint32_t fields_array_len_unsigned;
671  dbus_uint32_t body_len_unsigned;
672 
673  _dbus_assert (start >= 0);
674  _dbus_assert (start < _DBUS_INT32_MAX / 2);
675  _dbus_assert (len >= 0);
676 
677  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
678 
679  *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
680 
681  if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
682  {
683  *validity = DBUS_INVALID_BAD_BYTE_ORDER;
684  return FALSE;
685  }
686 
688  fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
689  *byte_order, NULL);
690 
691  if (fields_array_len_unsigned > (unsigned) max_message_length)
692  {
693  *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
694  return FALSE;
695  }
696 
697  _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
698  body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
699  *byte_order, NULL);
700 
701  if (body_len_unsigned > (unsigned) max_message_length)
702  {
703  *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
704  return FALSE;
705  }
706 
707  header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
708  header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
709 
710  /* overflow should be impossible since the lengths aren't allowed to
711  * be huge.
712  */
713  _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2);
714  if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
715  {
716  *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
717  return FALSE;
718  }
719 
720  _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX);
721  _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX);
722  _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX);
723 
724  *body_len = body_len_unsigned;
725  *fields_array_len = fields_array_len_unsigned;
726  *header_len = header_len_unsigned;
727 
728  *validity = DBUS_VALID;
729 
730  _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
731  len, body_len_unsigned, header_len_unsigned,
732  body_len_unsigned + header_len_unsigned);
733 
734  return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
735 }
736 
737 static DBusValidity
738 check_mandatory_fields (DBusHeader *header)
739 {
740 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
741 
742  switch (_dbus_header_get_message_type (header))
743  {
745  REQUIRE_FIELD (INTERFACE);
746  /* FALL THRU - signals also require the path and member */
748  REQUIRE_FIELD (PATH);
749  REQUIRE_FIELD (MEMBER);
750  break;
752  REQUIRE_FIELD (ERROR_NAME);
753  REQUIRE_FIELD (REPLY_SERIAL);
754  break;
756  REQUIRE_FIELD (REPLY_SERIAL);
757  break;
758  default:
759  /* other message types allowed but ignored */
760  break;
761  }
762 
763  return DBUS_VALID;
764 }
765 
766 static DBusValidity
767 load_and_validate_field (DBusHeader *header,
768  int field,
769  DBusTypeReader *variant_reader)
770 {
771  int type;
772  int expected_type;
773  const DBusString *value_str;
774  int value_pos;
775  int str_data_pos;
776  dbus_uint32_t v_UINT32;
777  int bad_string_code;
778  dbus_bool_t (* string_validation_func) (const DBusString *str,
779  int start, int len);
780 
781  /* Supposed to have been checked already */
784 
785  /* Before we can cache a field, we need to know it has the right type */
786  type = _dbus_type_reader_get_current_type (variant_reader);
787 
788  _dbus_assert (_dbus_header_field_types[field].code == field);
789 
790  expected_type = EXPECTED_TYPE_OF_FIELD (field);
791  if (type != expected_type)
792  {
793  _dbus_verbose ("Field %d should have type %d but has %d\n",
794  field, expected_type, type);
795  return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
796  }
797 
798  /* If the field was provided twice, we aren't happy */
799  if (header->fields[field].value_pos >= 0)
800  {
801  _dbus_verbose ("Header field %d seen a second time\n", field);
802  return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
803  }
804 
805  /* Now we can cache and look at the field content */
806  _dbus_verbose ("initially caching field %d\n", field);
807  _dbus_header_cache_one (header, field, variant_reader);
808 
809  string_validation_func = NULL;
810 
811  /* make compiler happy that all this is initialized */
812  v_UINT32 = 0;
813  value_str = NULL;
814  value_pos = -1;
815  str_data_pos = -1;
816  bad_string_code = DBUS_VALID;
817 
818  if (expected_type == DBUS_TYPE_UINT32)
819  {
820  _dbus_header_get_field_basic (header, field, expected_type,
821  &v_UINT32);
822  }
823  else if (expected_type == DBUS_TYPE_STRING ||
824  expected_type == DBUS_TYPE_OBJECT_PATH ||
825  expected_type == DBUS_TYPE_SIGNATURE)
826  {
827  _dbus_header_get_field_raw (header, field,
828  &value_str, &value_pos);
829  str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
830  }
831  else
832  {
833  _dbus_assert_not_reached ("none of the known fields should have this type");
834  }
835 
836  switch (field)
837  {
839  string_validation_func = _dbus_validate_bus_name;
840  bad_string_code = DBUS_INVALID_BAD_DESTINATION;
841  break;
843  string_validation_func = _dbus_validate_interface;
844  bad_string_code = DBUS_INVALID_BAD_INTERFACE;
845 
846  if (_dbus_string_equal_substring (&_dbus_local_interface_str,
847  0,
848  _dbus_string_get_length (&_dbus_local_interface_str),
849  value_str, str_data_pos))
850  {
851  _dbus_verbose ("Message is on the local interface\n");
852  return DBUS_INVALID_USES_LOCAL_INTERFACE;
853  }
854  break;
855 
857  string_validation_func = _dbus_validate_member;
858  bad_string_code = DBUS_INVALID_BAD_MEMBER;
859  break;
860 
862  string_validation_func = _dbus_validate_error_name;
863  bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
864  break;
865 
867  string_validation_func = _dbus_validate_bus_name;
868  bad_string_code = DBUS_INVALID_BAD_SENDER;
869  break;
870 
872  /* OBJECT_PATH was validated generically due to its type */
873  string_validation_func = NULL;
874 
875  if (_dbus_string_equal_substring (&_dbus_local_path_str,
876  0,
877  _dbus_string_get_length (&_dbus_local_path_str),
878  value_str, str_data_pos))
879  {
880  _dbus_verbose ("Message is from the local path\n");
881  return DBUS_INVALID_USES_LOCAL_PATH;
882  }
883  break;
884 
886  /* Can't be 0 */
887  if (v_UINT32 == 0)
888  {
889  return DBUS_INVALID_BAD_SERIAL;
890  }
891  break;
892 
894  /* Every value makes sense */
895  break;
896 
898  /* SIGNATURE validated generically due to its type */
899  string_validation_func = NULL;
900  break;
901 
902  default:
903  _dbus_assert_not_reached ("unknown field shouldn't be seen here");
904  break;
905  }
906 
907  if (string_validation_func)
908  {
909  dbus_uint32_t len;
910 
911  _dbus_assert (bad_string_code != DBUS_VALID);
912 
913  len = _dbus_marshal_read_uint32 (value_str, value_pos,
914  header->byte_order, NULL);
915 
916 #if 0
917  _dbus_verbose ("Validating string header field; code %d if fails\n",
918  bad_string_code);
919 #endif
920  if (!(*string_validation_func) (value_str, str_data_pos, len))
921  return bad_string_code;
922  }
923 
924  return DBUS_VALID;
925 }
926 
955  DBusValidationMode mode,
956  DBusValidity *validity,
957  int byte_order,
958  int fields_array_len,
959  int header_len,
960  int body_len,
961  const DBusString *str,
962  int start,
963  int len)
964 {
965  int leftover;
966  DBusValidity v;
967  DBusTypeReader reader;
968  DBusTypeReader array_reader;
969  unsigned char v_byte;
970  dbus_uint32_t v_uint32;
971  dbus_uint32_t serial;
972  int padding_start;
973  int padding_len;
974  int i;
975 
976  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
977  _dbus_assert (header_len <= len);
978  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
979 
980  if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
981  {
982  _dbus_verbose ("Failed to copy buffer into new header\n");
984  return FALSE;
985  }
986 
987  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
988  {
989  leftover = len - header_len - body_len - start;
990  }
991  else
992  {
993  v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
994  byte_order,
995  &leftover,
996  str, start, len);
997 
998  if (v != DBUS_VALID)
999  {
1000  *validity = v;
1001  goto invalid;
1002  }
1003  }
1004 
1005  _dbus_assert (leftover < len);
1006 
1007  padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
1008  padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
1009  _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
1010  _dbus_assert (start + header_len == padding_start + padding_len);
1011 
1012  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1013  {
1014  if (!_dbus_string_validate_nul (str, padding_start, padding_len))
1015  {
1016  *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1017  goto invalid;
1018  }
1019  }
1020 
1021  header->padding = padding_len;
1022 
1023  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1024  {
1025  *validity = DBUS_VALID;
1026  return TRUE;
1027  }
1028 
1029  /* We now know the data is well-formed, but we have to check that
1030  * it's valid.
1031  */
1032 
1033  _dbus_type_reader_init (&reader,
1034  byte_order,
1035  &_dbus_header_signature_str, 0,
1036  str, start);
1037 
1038  /* BYTE ORDER */
1041  _dbus_type_reader_read_basic (&reader, &v_byte);
1042  _dbus_type_reader_next (&reader);
1043 
1044  _dbus_assert (v_byte == byte_order);
1045  header->byte_order = byte_order;
1046 
1047  /* MESSAGE TYPE */
1050  _dbus_type_reader_read_basic (&reader, &v_byte);
1051  _dbus_type_reader_next (&reader);
1052 
1053  /* unknown message types are supposed to be ignored, so only validation here is
1054  * that it isn't invalid
1055  */
1056  if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1057  {
1058  *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1059  goto invalid;
1060  }
1061 
1062  /* FLAGS */
1065  _dbus_type_reader_read_basic (&reader, &v_byte);
1066  _dbus_type_reader_next (&reader);
1067 
1068  /* unknown flags should be ignored */
1069 
1070  /* PROTOCOL VERSION */
1073  _dbus_type_reader_read_basic (&reader, &v_byte);
1074  _dbus_type_reader_next (&reader);
1075 
1076  if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1077  {
1078  *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1079  goto invalid;
1080  }
1081 
1082  /* BODY LENGTH */
1085  _dbus_type_reader_read_basic (&reader, &v_uint32);
1086  _dbus_type_reader_next (&reader);
1087 
1088  _dbus_assert (body_len == (signed) v_uint32);
1089 
1090  /* SERIAL */
1093  _dbus_type_reader_read_basic (&reader, &serial);
1094  _dbus_type_reader_next (&reader);
1095 
1096  if (serial == 0)
1097  {
1098  *validity = DBUS_INVALID_BAD_SERIAL;
1099  goto invalid;
1100  }
1101 
1104 
1105  _dbus_type_reader_recurse (&reader, &array_reader);
1106  while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1107  {
1108  DBusTypeReader struct_reader;
1109  DBusTypeReader variant_reader;
1110  unsigned char field_code;
1111 
1113 
1114  _dbus_type_reader_recurse (&array_reader, &struct_reader);
1115 
1117  _dbus_type_reader_read_basic (&struct_reader, &field_code);
1118  _dbus_type_reader_next (&struct_reader);
1119 
1120  if (field_code == DBUS_HEADER_FIELD_INVALID)
1121  {
1122  _dbus_verbose ("invalid header field code\n");
1123  *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1124  goto invalid;
1125  }
1126 
1127  if (field_code > DBUS_HEADER_FIELD_LAST)
1128  {
1129  _dbus_verbose ("unknown header field code %d, skipping\n",
1130  field_code);
1131  goto next_field;
1132  }
1133 
1135  _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1136 
1137  v = load_and_validate_field (header, field_code, &variant_reader);
1138  if (v != DBUS_VALID)
1139  {
1140  _dbus_verbose ("Field %d was invalid\n", field_code);
1141  *validity = v;
1142  goto invalid;
1143  }
1144 
1145  next_field:
1146  _dbus_type_reader_next (&array_reader);
1147  }
1148 
1149  /* Anything we didn't fill in is now known not to exist */
1150  i = 0;
1151  while (i <= DBUS_HEADER_FIELD_LAST)
1152  {
1153  if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1154  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1155  ++i;
1156  }
1157 
1158  v = check_mandatory_fields (header);
1159  if (v != DBUS_VALID)
1160  {
1161  _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1162  *validity = v;
1163  goto invalid;
1164  }
1165 
1166  *validity = DBUS_VALID;
1167  return TRUE;
1168 
1169  invalid:
1170  _dbus_string_set_length (&header->data, 0);
1171  return FALSE;
1172 }
1173 
1180 void
1182  int body_len)
1183 {
1184  _dbus_marshal_set_uint32 (&header->data,
1186  body_len,
1187  header->byte_order);
1188 }
1189 
1190 static dbus_bool_t
1191 find_field_for_modification (DBusHeader *header,
1192  int field,
1193  DBusTypeReader *reader,
1194  DBusTypeReader *realign_root)
1195 {
1196  dbus_bool_t retval;
1197 
1198  retval = FALSE;
1199 
1200  _dbus_type_reader_init (realign_root,
1201  header->byte_order,
1202  &_dbus_header_signature_str,
1204  &header->data,
1206 
1207  _dbus_type_reader_recurse (realign_root, reader);
1208 
1210  {
1211  DBusTypeReader sub;
1212  unsigned char field_code;
1213 
1214  _dbus_type_reader_recurse (reader, &sub);
1215 
1217  _dbus_type_reader_read_basic (&sub, &field_code);
1218 
1219  if (field_code == (unsigned) field)
1220  {
1222  retval = TRUE;
1223  goto done;
1224  }
1225 
1226  _dbus_type_reader_next (reader);
1227  }
1228 
1229  done:
1230  return retval;
1231 }
1232 
1246  int field,
1247  int type,
1248  const void *value)
1249 {
1251 
1252  if (!reserve_header_padding (header))
1253  return FALSE;
1254 
1255  /* If the field exists we set, otherwise we append */
1256  if (_dbus_header_cache_check (header, field))
1257  {
1258  DBusTypeReader reader;
1259  DBusTypeReader realign_root;
1260 
1261  if (!find_field_for_modification (header, field,
1262  &reader, &realign_root))
1263  _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1264 
1265  if (!set_basic_field (&reader, field, type, value, &realign_root))
1266  return FALSE;
1267  }
1268  else
1269  {
1270  DBusTypeWriter writer;
1271  DBusTypeWriter array;
1272 
1274  header->byte_order,
1275  &_dbus_header_signature_str,
1277  &header->data,
1279 
1280  /* recurse into array without creating a new length, and jump to
1281  * end of array.
1282  */
1283  if (!_dbus_type_writer_append_array (&writer,
1284  &_dbus_header_signature_str,
1286  &array))
1287  _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1288 
1289  _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1290  _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1291  _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1292 
1293  if (!write_basic_field (&array,
1294  field, type, value))
1295  return FALSE;
1296 
1297  if (!_dbus_type_writer_unrecurse (&writer, &array))
1298  _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1299  }
1300 
1301  correct_header_padding (header);
1302 
1303  /* We could be smarter about this (only invalidate fields after the
1304  * one we modified, or even only if the one we modified changed
1305  * length). But this hack is a start.
1306  */
1307  _dbus_header_cache_invalidate_all (header);
1308 
1309  return TRUE;
1310 }
1311 
1324  int field,
1325  int type,
1326  void *value)
1327 {
1330  _dbus_assert (_dbus_header_field_types[field].code == field);
1331  /* in light of this you might ask why the type is passed in;
1332  * the only rationale I can think of is so the caller has
1333  * to specify its expectation and breaks if we change it
1334  */
1335  _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1336 
1337  if (!_dbus_header_cache_check (header, field))
1338  return FALSE;
1339 
1340  _dbus_assert (header->fields[field].value_pos >= 0);
1341 
1342  _dbus_marshal_read_basic (&header->data,
1343  header->fields[field].value_pos,
1344  type, value, header->byte_order,
1345  NULL);
1346 
1347  return TRUE;
1348 }
1349 
1365  int field,
1366  const DBusString **str,
1367  int *pos)
1368 {
1369  if (!_dbus_header_cache_check (header, field))
1370  return FALSE;
1371 
1372  if (str)
1373  *str = &header->data;
1374  if (pos)
1375  *pos = header->fields[field].value_pos;
1376 
1377  return TRUE;
1378 }
1379 
1389  int field)
1390 {
1391  DBusTypeReader reader;
1392  DBusTypeReader realign_root;
1393 
1394  if (_dbus_header_cache_known_nonexistent (header, field))
1395  return TRUE; /* nothing to do */
1396 
1397  /* Scan to the field we want, delete and realign, reappend
1398  * padding. Field may turn out not to exist.
1399  */
1400  if (!find_field_for_modification (header, field,
1401  &reader, &realign_root))
1402  return TRUE; /* nothing to do */
1403 
1404  if (!reserve_header_padding (header))
1405  return FALSE;
1406 
1407  if (!_dbus_type_reader_delete (&reader,
1408  &realign_root))
1409  return FALSE;
1410 
1411  correct_header_padding (header);
1412 
1413  _dbus_header_cache_invalidate_all (header);
1414 
1415  _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1416 
1417  return TRUE;
1418 }
1419 
1428 void
1430  dbus_uint32_t flag,
1431  dbus_bool_t value)
1432 {
1433  unsigned char *flags_p;
1434 
1435  flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1);
1436 
1437  if (value)
1438  *flags_p |= flag;
1439  else
1440  *flags_p &= ~flag;
1441 }
1442 
1452  dbus_uint32_t flag)
1453 {
1454  const unsigned char *flags_p;
1455 
1456  flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1);
1457 
1458  return (*flags_p & flag) != 0;
1459 }
1460 
1467 void
1469  int new_order)
1470 {
1471  if (header->byte_order == new_order)
1472  return;
1473 
1474  _dbus_marshal_byteswap (&_dbus_header_signature_str,
1475  0, header->byte_order,
1476  new_order,
1477  &header->data, 0);
1478 
1479  header->byte_order = new_order;
1480 }
1481 
1484 #ifdef DBUS_BUILD_TESTS
1485 #include "dbus-test.h"
1486 #include <stdio.h>
1487 
1489 _dbus_marshal_header_test (void)
1490 {
1491 
1492  return TRUE;
1493 }
1494 
1495 #endif /* DBUS_BUILD_TESTS */