D-Bus  1.12.20
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  */
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 #ifdef HAVE_PDPLINUX
88  ,{ DBUS_HEADER_FIELD_EXEC_SRC, DBUS_TYPE_STRING }
89  ,{ DBUS_HEADER_FIELD_EXEC_DST, DBUS_TYPE_STRING }
90 #endif
91 };
92 
94 #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type)
95 
97 #define MAX_POSSIBLE_HEADER_PADDING 7
98 static dbus_bool_t
99 reserve_header_padding (DBusHeader *header)
100 {
102 
103  if (!_dbus_string_lengthen (&header->data,
105  return FALSE;
107  return TRUE;
108 }
109 
110 static void
111 correct_header_padding (DBusHeader *header)
112 {
113  int unpadded_len;
114 
115  _dbus_assert (header->padding == 7);
116 
117  _dbus_string_shorten (&header->data, header->padding);
118  unpadded_len = _dbus_string_get_length (&header->data);
119 
120  if (!_dbus_string_align_length (&header->data, 8))
121  _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");
122 
123  header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
124 }
125 
127 #define HEADER_END_BEFORE_PADDING(header) \
128  (_dbus_string_get_length (&(header)->data) - (header)->padding)
129 
137 static void
138 _dbus_header_cache_invalidate_all (DBusHeader *header)
139 {
140  int i;
141 
142  i = 0;
143  while (i <= DBUS_HEADER_FIELD_LAST)
144  {
145  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN;
146  ++i;
147  }
148 }
149 
157 static void
158 _dbus_header_cache_one (DBusHeader *header,
159  int field_code,
160  DBusTypeReader *variant_reader)
161 {
162  header->fields[field_code].value_pos =
163  _dbus_type_reader_get_value_pos (variant_reader);
164 
165 #if 0
166  _dbus_verbose ("cached value_pos %d for field %d\n",
167  header->fields[field_code].value_pos, field_code)
168 #endif
169 }
170 
177 char
179 {
180  _dbus_assert (_dbus_string_get_length (&header->data) > BYTE_ORDER_OFFSET);
181 
182  return (char) _dbus_string_get_byte (&header->data, BYTE_ORDER_OFFSET);
183 }
184 
190 static void
191 _dbus_header_cache_revalidate (DBusHeader *header)
192 {
193  DBusTypeReader array;
194  DBusTypeReader reader;
195  int i;
196 
197  i = 0;
198  while (i <= DBUS_HEADER_FIELD_LAST)
199  {
200  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
201  ++i;
202  }
203 
204  _dbus_type_reader_init (&reader,
206  &_dbus_header_signature_str,
208  &header->data,
210 
211  _dbus_type_reader_recurse (&reader, &array);
212 
214  {
215  DBusTypeReader sub;
216  DBusTypeReader variant;
217  unsigned char field_code;
218 
219  _dbus_type_reader_recurse (&array, &sub);
220 
222  _dbus_type_reader_read_basic (&sub, &field_code);
223 
224  /* Unknown fields should be ignored */
225  if (field_code > DBUS_HEADER_FIELD_LAST)
226  goto next_field;
227 
228  _dbus_type_reader_next (&sub);
229 
231  _dbus_type_reader_recurse (&sub, &variant);
232 
233  _dbus_header_cache_one (header, field_code, &variant);
234 
235  next_field:
236  _dbus_type_reader_next (&array);
237  }
238 }
239 
247 static dbus_bool_t
248 _dbus_header_cache_check (DBusHeader *header,
249  int field)
250 {
252 
253  if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
254  _dbus_header_cache_revalidate (header);
255 
256  if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
257  return FALSE;
258 
259  return TRUE;
260 }
261 
270 static dbus_bool_t
271 _dbus_header_cache_known_nonexistent (DBusHeader *header,
272  int field)
273 {
275 
276  return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
277 }
278 
288 static dbus_bool_t
289 write_basic_field (DBusTypeWriter *writer,
290  int field,
291  int type,
292  const void *value)
293 {
294  DBusTypeWriter sub;
295  DBusTypeWriter variant;
296  int start;
297  int padding;
298  unsigned char field_byte;
299  DBusString contained_type;
300  char buf[2];
301 
302  start = writer->value_pos;
303  padding = _dbus_string_get_length (writer->value_str) - start;
304 
306  NULL, 0, &sub))
307  goto append_failed;
308 
309  field_byte = field;
311  &field_byte))
312  goto append_failed;
313 
314  buf[0] = type;
315  buf[1] = '\0';
316  _dbus_string_init_const_len (&contained_type, buf, 1);
317 
319  &contained_type, 0, &variant))
320  goto append_failed;
321 
322  if (!_dbus_type_writer_write_basic (&variant, type, value))
323  goto append_failed;
324 
325  if (!_dbus_type_writer_unrecurse (&sub, &variant))
326  goto append_failed;
327 
328  if (!_dbus_type_writer_unrecurse (writer, &sub))
329  goto append_failed;
330 
331  return TRUE;
332 
333  append_failed:
335  start,
336  _dbus_string_get_length (writer->value_str) - start - padding);
337  return FALSE;
338 }
339 
350 static dbus_bool_t
351 set_basic_field (DBusTypeReader *reader,
352  int field,
353  int type,
354  const void *value,
355  const DBusTypeReader *realign_root)
356 {
357  DBusTypeReader sub;
358  DBusTypeReader variant;
359 
360  _dbus_type_reader_recurse (reader, &sub);
361 
363 #ifndef DBUS_DISABLE_ASSERT
364  {
365  unsigned char v_BYTE;
366  _dbus_type_reader_read_basic (&sub, &v_BYTE);
367  _dbus_assert (((int) v_BYTE) == field);
368  }
369 #endif
370 
371  if (!_dbus_type_reader_next (&sub))
372  _dbus_assert_not_reached ("no variant field?");
373 
374  _dbus_type_reader_recurse (&sub, &variant);
376 
377  if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
378  return FALSE;
379 
380  return TRUE;
381 }
382 
389 int
391 {
392  int type;
393 
394  type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
396 
397  return type;
398 }
399 
407 void
409  dbus_uint32_t serial)
410 {
411  /* we use this function to set the serial on outgoing
412  * messages, and to reset the serial in dbus_message_copy;
413  * this assertion should catch a double-set on outgoing.
414  */
415  _dbus_assert (_dbus_header_get_serial (header) == 0 ||
416  serial == 0);
417 
418  _dbus_marshal_set_uint32 (&header->data,
420  serial,
421  _dbus_header_get_byte_order (header));
422 }
423 
430 dbus_uint32_t
432 {
433  return _dbus_marshal_read_uint32 (&header->data,
436  NULL);
437 }
438 
446 void
448 {
449  _dbus_string_set_length (&header->data, 0);
450 
451  header->padding = 0;
452 
453  _dbus_header_cache_invalidate_all (header);
454 }
455 
465 {
466  if (!_dbus_string_init_preallocated (&header->data, 32))
467  return FALSE;
468 
469  _dbus_header_reinit (header);
470 
471  return TRUE;
472 }
473 
479 void
481 {
482  _dbus_string_free (&header->data);
483 }
484 
495  DBusHeader *dest)
496 {
497  *dest = *header;
498 
500  _dbus_string_get_length (&header->data)))
501  return FALSE;
502 
503  if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
504  {
505  _dbus_string_free (&dest->data);
506  return FALSE;
507  }
508 
509  /* Reset the serial */
510  _dbus_header_set_serial (dest, 0);
511 
512  return TRUE;
513 }
514 
533  int byte_order,
534  int message_type,
535  const char *destination,
536  const char *path,
537  const char *interface,
538  const char *member,
539  const char *error_name)
540 {
541  unsigned char v_BYTE;
542  dbus_uint32_t v_UINT32;
543  DBusTypeWriter writer;
544  DBusTypeWriter array;
545 
546  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
547  byte_order == DBUS_BIG_ENDIAN);
548  _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
549  (error_name) ||
550  !(interface || member || error_name));
551  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
552 
553  if (!reserve_header_padding (header))
554  return FALSE;
555 
556  _dbus_type_writer_init_values_only (&writer, byte_order,
557  &_dbus_header_signature_str, 0,
558  &header->data,
559  HEADER_END_BEFORE_PADDING (header));
560 
561  v_BYTE = byte_order;
563  &v_BYTE))
564  goto oom;
565 
566  v_BYTE = message_type;
568  &v_BYTE))
569  goto oom;
570 
571  v_BYTE = 0; /* flags */
573  &v_BYTE))
574  goto oom;
575 
578  &v_BYTE))
579  goto oom;
580 
581  v_UINT32 = 0; /* body length */
583  &v_UINT32))
584  goto oom;
585 
586  v_UINT32 = 0; /* serial */
588  &v_UINT32))
589  goto oom;
590 
592  &_dbus_header_signature_str,
594  &array))
595  goto oom;
596 
597  /* Marshal all the fields (Marshall Fields?) */
598 
599  if (path != NULL)
600  {
601  if (!write_basic_field (&array,
604  &path))
605  goto oom;
606  }
607 
608  if (destination != NULL)
609  {
610  if (!write_basic_field (&array,
613  &destination))
614  goto oom;
615  }
616 
617  if (interface != NULL)
618  {
619  if (!write_basic_field (&array,
622  &interface))
623  goto oom;
624  }
625 
626  if (member != NULL)
627  {
628  if (!write_basic_field (&array,
631  &member))
632  goto oom;
633  }
634 
635  if (error_name != NULL)
636  {
637  if (!write_basic_field (&array,
640  &error_name))
641  goto oom;
642  }
643 
644  if (!_dbus_type_writer_unrecurse (&writer, &array))
645  goto oom;
646 
647  correct_header_padding (header);
648 
649  return TRUE;
650 
651  oom:
652  _dbus_string_delete (&header->data, 0,
653  _dbus_string_get_length (&header->data) - header->padding);
654  correct_header_padding (header);
655 
656  return FALSE;
657 }
658 
677 _dbus_header_have_message_untrusted (int max_message_length,
678  DBusValidity *validity,
679  int *byte_order,
680  int *fields_array_len,
681  int *header_len,
682  int *body_len,
683  const DBusString *str,
684  int start,
685  int len)
686 
687 {
688  dbus_uint32_t header_len_unsigned;
689  dbus_uint32_t fields_array_len_unsigned;
690  dbus_uint32_t body_len_unsigned;
691 
692  _dbus_assert (start >= 0);
693  _dbus_assert (start < _DBUS_INT32_MAX / 2);
694  _dbus_assert (len >= 0);
695 
696  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
697 
698  *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
699 
700  if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
701  {
702  *validity = DBUS_INVALID_BAD_BYTE_ORDER;
703  return FALSE;
704  }
705 
707  fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
708  *byte_order, NULL);
709 
710  if (fields_array_len_unsigned > (unsigned) max_message_length)
711  {
712  *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
713  return FALSE;
714  }
715 
716  _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
717  body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
718  *byte_order, NULL);
719 
720  if (body_len_unsigned > (unsigned) max_message_length)
721  {
722  *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
723  return FALSE;
724  }
725 
726  header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
727  header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
728 
729  /* overflow should be impossible since the lengths aren't allowed to
730  * be huge.
731  */
732  _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2);
733  if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
734  {
735  *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
736  return FALSE;
737  }
738 
739  _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX);
740  _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX);
741  _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX);
742 
743  *body_len = body_len_unsigned;
744  *fields_array_len = fields_array_len_unsigned;
745  *header_len = header_len_unsigned;
746 
747  *validity = DBUS_VALID;
748 
749  _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
750  len, body_len_unsigned, header_len_unsigned,
751  body_len_unsigned + header_len_unsigned);
752 
753  return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
754 }
755 
756 static DBusValidity
757 check_mandatory_fields (DBusHeader *header)
758 {
759 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
760 
761  switch (_dbus_header_get_message_type (header))
762  {
764  REQUIRE_FIELD (INTERFACE);
765  /* FALL THRU - signals also require the path and member */
767  REQUIRE_FIELD (PATH);
768  REQUIRE_FIELD (MEMBER);
769  break;
771  REQUIRE_FIELD (ERROR_NAME);
772  REQUIRE_FIELD (REPLY_SERIAL);
773  break;
775  REQUIRE_FIELD (REPLY_SERIAL);
776  break;
777  default:
778  /* other message types allowed but ignored */
779  break;
780  }
781 
782  return DBUS_VALID;
783 }
784 
785 static DBusValidity
786 load_and_validate_field (DBusHeader *header,
787  int field,
788  DBusTypeReader *variant_reader)
789 {
790  int type;
791  int expected_type;
792  const DBusString *value_str;
793  int value_pos;
794  int str_data_pos;
795  dbus_uint32_t v_UINT32;
796  int bad_string_code;
797  dbus_bool_t (* string_validation_func) (const DBusString *str,
798  int start, int len);
799 
800  /* Supposed to have been checked already */
803 
804  /* Before we can cache a field, we need to know it has the right type */
805  type = _dbus_type_reader_get_current_type (variant_reader);
806 
807  _dbus_assert (_dbus_header_field_types[field].code == field);
808 
809  expected_type = EXPECTED_TYPE_OF_FIELD (field);
810  if (type != expected_type)
811  {
812  _dbus_verbose ("Field %d should have type %d but has %d\n",
813  field, expected_type, type);
814  return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
815  }
816 
817  /* If the field was provided twice, we aren't happy */
818  if (header->fields[field].value_pos >= 0)
819  {
820  _dbus_verbose ("Header field %d seen a second time\n", field);
821  return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
822  }
823 
824  /* Now we can cache and look at the field content */
825  _dbus_verbose ("initially caching field %d\n", field);
826  _dbus_header_cache_one (header, field, variant_reader);
827 
828  string_validation_func = NULL;
829 
830  /* make compiler happy that all this is initialized */
831  v_UINT32 = 0;
832  value_str = NULL;
833  value_pos = -1;
834  str_data_pos = -1;
835  bad_string_code = DBUS_VALID;
836 
837  if (expected_type == DBUS_TYPE_UINT32)
838  {
839  _dbus_header_get_field_basic (header, field, expected_type,
840  &v_UINT32);
841  }
842  else if (expected_type == DBUS_TYPE_STRING ||
843  expected_type == DBUS_TYPE_OBJECT_PATH ||
844  expected_type == DBUS_TYPE_SIGNATURE)
845  {
846  _dbus_header_get_field_raw (header, field,
847  &value_str, &value_pos);
848  str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
849  }
850  else
851  {
852  _dbus_assert_not_reached ("none of the known fields should have this type");
853  }
854 
855  switch (field)
856  {
858  string_validation_func = _dbus_validate_bus_name;
859  bad_string_code = DBUS_INVALID_BAD_DESTINATION;
860  break;
862  string_validation_func = _dbus_validate_interface;
863  bad_string_code = DBUS_INVALID_BAD_INTERFACE;
864 
865  if (_dbus_string_equal_substring (&_dbus_local_interface_str,
866  0,
867  _dbus_string_get_length (&_dbus_local_interface_str),
868  value_str, str_data_pos))
869  {
870  _dbus_verbose ("Message is on the local interface\n");
871  return DBUS_INVALID_USES_LOCAL_INTERFACE;
872  }
873  break;
874 
876  string_validation_func = _dbus_validate_member;
877  bad_string_code = DBUS_INVALID_BAD_MEMBER;
878  break;
879 
881  string_validation_func = _dbus_validate_error_name;
882  bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
883  break;
884 
886  string_validation_func = _dbus_validate_bus_name;
887  bad_string_code = DBUS_INVALID_BAD_SENDER;
888  break;
889 
891  /* OBJECT_PATH was validated generically due to its type */
892  string_validation_func = NULL;
893 
894  if (_dbus_string_equal_substring (&_dbus_local_path_str,
895  0,
896  _dbus_string_get_length (&_dbus_local_path_str),
897  value_str, str_data_pos))
898  {
899  _dbus_verbose ("Message is from the local path\n");
900  return DBUS_INVALID_USES_LOCAL_PATH;
901  }
902  break;
903 
905  /* Can't be 0 */
906  if (v_UINT32 == 0)
907  {
908  return DBUS_INVALID_BAD_SERIAL;
909  }
910  break;
911 
913  /* Every value makes sense */
914  break;
915 
916 #ifdef HAVE_PDPLINUX
917  case DBUS_HEADER_FIELD_EXEC_SRC:
918  /* Every value makes sense */
919  break;
920  case DBUS_HEADER_FIELD_EXEC_DST:
921  /* Every value makes sense */
922  break;
923 #endif
924 
926  /* SIGNATURE validated generically due to its type */
927  string_validation_func = NULL;
928  break;
929 
930  default:
931  _dbus_assert_not_reached ("unknown field shouldn't be seen here");
932  break;
933  }
934 
935  if (string_validation_func)
936  {
937  dbus_uint32_t len;
938 
939  _dbus_assert (bad_string_code != DBUS_VALID);
940 
941  len = _dbus_marshal_read_uint32 (value_str, value_pos,
943  NULL);
944 
945 #if 0
946  _dbus_verbose ("Validating string header field; code %d if fails\n",
947  bad_string_code);
948 #endif
949  if (!(*string_validation_func) (value_str, str_data_pos, len))
950  return bad_string_code;
951  }
952 
953  return DBUS_VALID;
954 }
955 
984  DBusValidationMode mode,
985  DBusValidity *validity,
986  int byte_order,
987  int fields_array_len,
988  int header_len,
989  int body_len,
990  const DBusString *str,
991  int start,
992  int len)
993 {
994  int leftover;
995  DBusValidity v;
996  DBusTypeReader reader;
997  DBusTypeReader array_reader;
998  unsigned char v_byte;
999  dbus_uint32_t v_uint32;
1000  dbus_uint32_t serial;
1001  int padding_start;
1002  int padding_len;
1003  int i;
1004 
1005  _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
1006  _dbus_assert (header_len <= len);
1007  _dbus_assert (_dbus_string_get_length (&header->data) == 0);
1008 
1009  if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
1010  {
1011  _dbus_verbose ("Failed to copy buffer into new header\n");
1012  *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
1013  return FALSE;
1014  }
1015 
1016  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1017  {
1018  leftover = len - header_len - body_len - start;
1019  }
1020  else
1021  {
1022  v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
1023  byte_order,
1024  &leftover,
1025  str, start, len);
1026 
1027  if (v != DBUS_VALID)
1028  {
1029  *validity = v;
1030  goto invalid;
1031  }
1032  }
1033 
1034  _dbus_assert (leftover < len);
1035 
1036  padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
1037  padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
1038  _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
1039  _dbus_assert (start + header_len == padding_start + padding_len);
1040 
1041  if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1042  {
1043  if (!_dbus_string_validate_nul (str, padding_start, padding_len))
1044  {
1045  *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1046  goto invalid;
1047  }
1048  }
1049 
1050  header->padding = padding_len;
1051 
1052  if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1053  {
1054  *validity = DBUS_VALID;
1055  return TRUE;
1056  }
1057 
1058  /* We now know the data is well-formed, but we have to check that
1059  * it's valid.
1060  */
1061 
1062  _dbus_type_reader_init (&reader,
1063  byte_order,
1064  &_dbus_header_signature_str, 0,
1065  str, start);
1066 
1067  /* BYTE ORDER */
1070  _dbus_type_reader_read_basic (&reader, &v_byte);
1071  _dbus_type_reader_next (&reader);
1072 
1073  _dbus_assert (v_byte == byte_order);
1074 
1075  /* MESSAGE TYPE */
1078  _dbus_type_reader_read_basic (&reader, &v_byte);
1079  _dbus_type_reader_next (&reader);
1080 
1081  /* unknown message types are supposed to be ignored, so only validation here is
1082  * that it isn't invalid
1083  */
1084  if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1085  {
1086  *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1087  goto invalid;
1088  }
1089 
1090  /* FLAGS */
1093  _dbus_type_reader_read_basic (&reader, &v_byte);
1094  _dbus_type_reader_next (&reader);
1095 
1096  /* unknown flags should be ignored */
1097 
1098  /* PROTOCOL VERSION */
1101  _dbus_type_reader_read_basic (&reader, &v_byte);
1102  _dbus_type_reader_next (&reader);
1103 
1104  if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1105  {
1106  *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1107  goto invalid;
1108  }
1109 
1110  /* BODY LENGTH */
1113  _dbus_type_reader_read_basic (&reader, &v_uint32);
1114  _dbus_type_reader_next (&reader);
1115 
1116  _dbus_assert (body_len == (signed) v_uint32);
1117 
1118  /* SERIAL */
1121  _dbus_type_reader_read_basic (&reader, &serial);
1122  _dbus_type_reader_next (&reader);
1123 
1124  if (serial == 0)
1125  {
1126  *validity = DBUS_INVALID_BAD_SERIAL;
1127  goto invalid;
1128  }
1129 
1132 
1133  _dbus_type_reader_recurse (&reader, &array_reader);
1134  while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1135  {
1136  DBusTypeReader struct_reader;
1137  DBusTypeReader variant_reader;
1138  unsigned char field_code;
1139 
1141 
1142  _dbus_type_reader_recurse (&array_reader, &struct_reader);
1143 
1145  _dbus_type_reader_read_basic (&struct_reader, &field_code);
1146  _dbus_type_reader_next (&struct_reader);
1147 
1148  if (field_code == DBUS_HEADER_FIELD_INVALID)
1149  {
1150  _dbus_verbose ("invalid header field code\n");
1151  *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1152  goto invalid;
1153  }
1154 
1155  if (field_code > DBUS_HEADER_FIELD_LAST)
1156  {
1157  _dbus_verbose ("unknown header field code %d, skipping\n",
1158  field_code);
1159  goto next_field;
1160  }
1161 
1163  _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1164 
1165  v = load_and_validate_field (header, field_code, &variant_reader);
1166  if (v != DBUS_VALID)
1167  {
1168  _dbus_verbose ("Field %d was invalid\n", field_code);
1169  *validity = v;
1170  goto invalid;
1171  }
1172 
1173  next_field:
1174  _dbus_type_reader_next (&array_reader);
1175  }
1176 
1177  /* Anything we didn't fill in is now known not to exist */
1178  i = 0;
1179  while (i <= DBUS_HEADER_FIELD_LAST)
1180  {
1181  if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1182  header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1183  ++i;
1184  }
1185 
1186  v = check_mandatory_fields (header);
1187  if (v != DBUS_VALID)
1188  {
1189  _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1190  *validity = v;
1191  goto invalid;
1192  }
1193 
1194  *validity = DBUS_VALID;
1195  return TRUE;
1196 
1197  invalid:
1198  _dbus_string_set_length (&header->data, 0);
1199  return FALSE;
1200 }
1201 
1208 void
1210  int body_len)
1211 {
1212  _dbus_marshal_set_uint32 (&header->data,
1214  body_len,
1215  _dbus_header_get_byte_order (header));
1216 }
1217 
1231 static dbus_bool_t
1232 find_field_for_modification (DBusHeader *header,
1233  int field,
1234  DBusTypeReader *reader,
1235  DBusTypeReader *realign_root)
1236 {
1237  dbus_bool_t retval;
1238 
1239  retval = FALSE;
1240 
1241  _dbus_type_reader_init (realign_root,
1242  _dbus_header_get_byte_order (header),
1243  &_dbus_header_signature_str,
1245  &header->data,
1247 
1248  _dbus_type_reader_recurse (realign_root, reader);
1249 
1251  {
1252  DBusTypeReader sub;
1253  unsigned char field_code;
1254 
1255  _dbus_type_reader_recurse (reader, &sub);
1256 
1258  _dbus_type_reader_read_basic (&sub, &field_code);
1259 
1260  if (field_code == (unsigned) field)
1261  {
1263  retval = TRUE;
1264  goto done;
1265  }
1266 
1267  _dbus_type_reader_next (reader);
1268  }
1269 
1270  done:
1271  return retval;
1272 }
1273 
1287  int field,
1288  int type,
1289  const void *value)
1290 {
1292 
1293  if (!reserve_header_padding (header))
1294  return FALSE;
1295 
1296  /* If the field exists we set, otherwise we append */
1297  if (_dbus_header_cache_check (header, field))
1298  {
1299  DBusTypeReader reader;
1300  DBusTypeReader realign_root;
1301 
1302  if (!find_field_for_modification (header, field,
1303  &reader, &realign_root))
1304  _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1305 
1306  if (!set_basic_field (&reader, field, type, value, &realign_root))
1307  return FALSE;
1308  }
1309  else
1310  {
1311  DBusTypeWriter writer;
1312  DBusTypeWriter array;
1313 
1315  _dbus_header_get_byte_order (header),
1316  &_dbus_header_signature_str,
1318  &header->data,
1320 
1321  /* recurse into array without creating a new length, and jump to
1322  * end of array.
1323  */
1324  if (!_dbus_type_writer_append_array (&writer,
1325  &_dbus_header_signature_str,
1327  &array))
1328  _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1329 
1330  _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1331  _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1332  _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1333 
1334  if (!write_basic_field (&array,
1335  field, type, value))
1336  return FALSE;
1337 
1338  if (!_dbus_type_writer_unrecurse (&writer, &array))
1339  _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1340  }
1341 
1342  correct_header_padding (header);
1343 
1344  /* We could be smarter about this (only invalidate fields after the
1345  * one we modified, or even only if the one we modified changed
1346  * length). But this hack is a start.
1347  */
1348  _dbus_header_cache_invalidate_all (header);
1349 
1350  return TRUE;
1351 }
1352 
1365  int field,
1366  int type,
1367  void *value)
1368 {
1371  _dbus_assert (_dbus_header_field_types[field].code == field);
1372  /* in light of this you might ask why the type is passed in;
1373  * the only rationale I can think of is so the caller has
1374  * to specify its expectation and breaks if we change it
1375  */
1376  _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1377 
1378  if (!_dbus_header_cache_check (header, field))
1379  return FALSE;
1380 
1381  _dbus_assert (header->fields[field].value_pos >= 0);
1382 
1383  _dbus_marshal_read_basic (&header->data,
1384  header->fields[field].value_pos,
1385  type, value, _dbus_header_get_byte_order (header),
1386  NULL);
1387 
1388  return TRUE;
1389 }
1390 
1406  int field,
1407  const DBusString **str,
1408  int *pos)
1409 {
1410  if (!_dbus_header_cache_check (header, field))
1411  return FALSE;
1412 
1413  if (str)
1414  *str = &header->data;
1415  if (pos)
1416  *pos = header->fields[field].value_pos;
1417 
1418  return TRUE;
1419 }
1420 
1430  int field)
1431 {
1432  DBusTypeReader reader;
1433  DBusTypeReader realign_root;
1434 
1435  if (_dbus_header_cache_known_nonexistent (header, field))
1436  return TRUE; /* nothing to do */
1437 
1438  /* Scan to the field we want, delete and realign, reappend
1439  * padding. Field may turn out not to exist.
1440  */
1441  if (!find_field_for_modification (header, field,
1442  &reader, &realign_root))
1443  return TRUE; /* nothing to do */
1444 
1445  if (!reserve_header_padding (header))
1446  return FALSE;
1447 
1448  if (!_dbus_type_reader_delete (&reader,
1449  &realign_root))
1450  return FALSE;
1451 
1452  correct_header_padding (header);
1453 
1454  _dbus_header_cache_invalidate_all (header);
1455 
1456  _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1457 
1458  return TRUE;
1459 }
1460 
1469 void
1471  dbus_uint32_t flag,
1472  dbus_bool_t value)
1473 {
1474  unsigned char *flags_p;
1475 
1476  flags_p = _dbus_string_get_udata_len (&header->data, FLAGS_OFFSET, 1);
1477 
1478  if (value)
1479  *flags_p |= flag;
1480  else
1481  *flags_p &= ~flag;
1482 }
1483 
1493  dbus_uint32_t flag)
1494 {
1495  const unsigned char *flags_p;
1496 
1497  flags_p = _dbus_string_get_const_udata_len (&header->data, FLAGS_OFFSET, 1);
1498 
1499  return (*flags_p & flag) != 0;
1500 }
1501 
1508 void
1510  int new_order)
1511 {
1512  char byte_order;
1513 
1514  byte_order = _dbus_header_get_byte_order (header);
1515 
1516  if (byte_order == new_order)
1517  return;
1518 
1519  _dbus_marshal_byteswap (&_dbus_header_signature_str,
1520  0, byte_order,
1521  new_order,
1522  &header->data, 0);
1523 
1524  _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order);
1525 }
1526 
DBUS_TYPE_ARRAY
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
Definition: dbus-protocol.h:120
DBUS_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition: dbus-protocol.h:102
DBUS_MAJOR_PROTOCOL_VERSION
#define DBUS_MAJOR_PROTOCOL_VERSION
Protocol version.
Definition: dbus-protocol.h:57
HeaderFieldType
Definition: dbus-marshal-header.c:70
_dbus_type_reader_next
dbus_bool_t _dbus_type_reader_next(DBusTypeReader *reader)
Skip to the next value on this "level".
Definition: dbus-marshal-recursive.c:1055
DBusHeader::data
DBusString data
Header network data, stored separately from body so we can independently realloc it.
Definition: dbus-marshal-header.h:49
DBusValidationMode
DBusValidationMode
This is used rather than a bool for high visibility.
Definition: dbus-marshal-validate.h:37
DBUS_TYPE_INVALID
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
DBUS_VALID
@ DBUS_VALID
the data is valid
Definition: dbus-marshal-validate.h:56
DBusTypeWriter::value_pos
int value_pos
next position to write
Definition: dbus-marshal-recursive.h:77
_dbus_header_update_lengths
void _dbus_header_update_lengths(DBusHeader *header, int body_len)
Fills in the correct body length.
Definition: dbus-marshal-header.c:1209
DBusHeader::padding
dbus_uint32_t padding
bytes of alignment in header
Definition: dbus-marshal-header.h:58
_dbus_type_writer_init_values_only
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...
Definition: dbus-marshal-recursive.c:1585
DBusTypeWriter::u
union DBusTypeWriter::@3 u
class-specific data
DBUS_HEADER_FIELD_LAST
#define DBUS_HEADER_FIELD_LAST
Value of the highest-numbered header field code, can be used to determine the size of an array indexe...
Definition: dbus-protocol.h:320
_dbus_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
FIRST_FIELD_OFFSET
#define FIRST_FIELD_OFFSET
Offset to first field in header.
Definition: dbus-marshal-header.c:67
_dbus_type_writer_append_array
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.
Definition: dbus-marshal-recursive.c:2144
DBUS_HEADER_FIELD_SENDER
#define DBUS_HEADER_FIELD_SENDER
Header field code for the sender of a message; usually initialized by the message bus.
Definition: dbus-protocol.h:293
_dbus_type_writer_recurse
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.
Definition: dbus-marshal-recursive.c:2110
_dbus_type_reader_set_basic
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...
Definition: dbus-marshal-recursive.c:1364
DBUS_HEADER_FIELD_PATH
#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...
Definition: dbus-protocol.h:270
_dbus_header_set_serial
void _dbus_header_set_serial(DBusHeader *header, dbus_uint32_t serial)
Sets the serial number of a header.
Definition: dbus-marshal-header.c:408
_dbus_string_copy
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's copied to the d...
Definition: dbus-string.c:1283
_dbus_string_lengthen
dbus_bool_t _dbus_string_lengthen(DBusString *str, int additional_length)
Makes a string longer by the given number of bytes.
Definition: dbus-string.c:760
_dbus_type_reader_read_basic
void _dbus_type_reader_read_basic(const DBusTypeReader *reader, void *value)
Reads a basic-typed value, as with _dbus_marshal_read_basic().
Definition: dbus-marshal-recursive.c:870
_dbus_header_delete_field
dbus_bool_t _dbus_header_delete_field(DBusHeader *header, int field)
Deletes a field, if it exists.
Definition: dbus-marshal-header.c:1429
_dbus_header_get_serial
dbus_uint32_t _dbus_header_get_serial(DBusHeader *header)
See dbus_message_get_serial()
Definition: dbus-marshal-header.c:431
_dbus_validate_body_with_reason
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...
Definition: dbus-marshal-validate.c:708
DBUS_MESSAGE_TYPE_METHOD_CALL
#define DBUS_MESSAGE_TYPE_METHOD_CALL
Message type of a method call message, see dbus_message_get_type()
Definition: dbus-protocol.h:234
DBusHeader
Message header data and some cached details of it.
Definition: dbus-marshal-header.h:48
DBUS_LITTLE_ENDIAN
#define DBUS_LITTLE_ENDIAN
Code marking LSB-first byte order in the wire protocol.
Definition: dbus-protocol.h:53
DBUS_BIG_ENDIAN
#define DBUS_BIG_ENDIAN
Code marking MSB-first byte order in the wire protocol.
Definition: dbus-protocol.h:54
_dbus_header_load
dbus_bool_t _dbus_header_load(DBusHeader *header, DBusValidationMode mode, DBusValidity *validity, int byte_order, int fields_array_len, int header_len, int body_len, const DBusString *str, int start, int len)
Creates a message header from potentially-untrusted data.
Definition: dbus-marshal-header.c:983
DBUS_HEADER_FIELD_SIGNATURE
#define DBUS_HEADER_FIELD_SIGNATURE
Header field code for the type signature of a message.
Definition: dbus-protocol.h:297
_dbus_header_get_byte_order
char _dbus_header_get_byte_order(const DBusHeader *header)
Returns the header's byte order.
Definition: dbus-marshal-header.c:178
_dbus_header_get_message_type
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
Definition: dbus-marshal-header.c:390
_dbus_string_validate_nul
dbus_bool_t _dbus_string_validate_nul(const DBusString *str, int start, int len)
Checks that the given range of the string is all nul bytes.
Definition: dbus-string.c:2653
DBusHeaderField::value_pos
int value_pos
Position of field value, or -1/-2.
Definition: dbus-marshal-header.h:41
_dbus_validate_bus_name
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.
Definition: dbus-marshal-validate.c:1194
TRUE
#define TRUE
Expands to "1".
MAX_POSSIBLE_HEADER_PADDING
#define MAX_POSSIBLE_HEADER_PADDING
The most padding we could ever need for a header.
Definition: dbus-marshal-header.c:97
SERIAL_OFFSET
#define SERIAL_OFFSET
Offset to client serial from start of header.
Definition: dbus-marshal-header.c:63
DBusTypeWriter::value_str
DBusString * value_str
where to write values
Definition: dbus-marshal-recursive.h:76
DBusTypeReader
The type reader is an iterator for reading values from a block of values.
Definition: dbus-marshal-recursive.h:40
DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
Definition: dbus-protocol.h:110
_dbus_header_toggle_flag
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.
Definition: dbus-marshal-header.c:1470
FIELDS_ARRAY_LENGTH_OFFSET
#define FIELDS_ARRAY_LENGTH_OFFSET
Offset to fields array length from start of header.
Definition: dbus-marshal-header.c:65
_dbus_marshal_read_basic
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.
Definition: dbus-marshal-basic.c:496
_dbus_string_init_preallocated
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
DBusString
Definition: dbus-string.h:43
DBUS_HEADER_FIELD_INTERFACE
#define DBUS_HEADER_FIELD_INTERFACE
Header field code for the interface containing a member (method or signal).
Definition: dbus-protocol.h:274
_dbus_marshal_read_uint32
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.
Definition: dbus-marshal-basic.c:458
HeaderFieldType::code
unsigned char code
the field code
Definition: dbus-marshal-header.c:71
BODY_LENGTH_OFFSET
#define BODY_LENGTH_OFFSET
Offset to body length from start of header.
Definition: dbus-marshal-header.c:61
_dbus_type_reader_init
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.
Definition: dbus-marshal-recursive.c:733
_dbus_type_reader_get_value_pos
int _dbus_type_reader_get_value_pos(const DBusTypeReader *reader)
Gets the current position in the value block.
Definition: dbus-marshal-recursive.c:838
DBUS_MESSAGE_TYPE_SIGNAL
#define DBUS_MESSAGE_TYPE_SIGNAL
Message type of a signal message, see dbus_message_get_type()
Definition: dbus-protocol.h:240
DBUS_TYPE_STRUCT
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can't appear in a type string,...
Definition: dbus-protocol.h:136
DBUS_TYPE_BYTE
#define DBUS_TYPE_BYTE
Type code marking an 8-bit unsigned integer.
Definition: dbus-protocol.h:66
_dbus_header_get_flag
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.
Definition: dbus-marshal-header.c:1492
_dbus_type_reader_get_current_type
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...
Definition: dbus-marshal-recursive.c:786
_dbus_type_reader_delete
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.
Definition: dbus-marshal-recursive.c:1421
FALSE
#define FALSE
Expands to "0".
DBUS_HEADER_SIGNATURE
#define DBUS_HEADER_SIGNATURE
Header format is defined as a signature: byte byte order byte message type ID byte flags byte protoco...
Definition: dbus-protocol.h:339
HeaderFieldType::type
unsigned char type
the value type
Definition: dbus-marshal-header.c:72
_dbus_header_copy
dbus_bool_t _dbus_header_copy(const DBusHeader *header, DBusHeader *dest)
Initializes dest with a copy of the given header.
Definition: dbus-marshal-header.c:494
BYTE_ORDER_OFFSET
#define BYTE_ORDER_OFFSET
Offset to byte order from start of header.
Definition: dbus-marshal-header.c:53
FLAGS_OFFSET
#define FLAGS_OFFSET
Offset to flags from start of header.
Definition: dbus-marshal-header.c:57
_dbus_string_delete
void _dbus_string_delete(DBusString *str, int start, int len)
Deletes a segment of a DBusString with length len starting at start.
Definition: dbus-string.c:1193
DBUS_MESSAGE_TYPE_ERROR
#define DBUS_MESSAGE_TYPE_ERROR
Message type of an error reply message, see dbus_message_get_type()
Definition: dbus-protocol.h:238
DBUS_MESSAGE_TYPE_METHOD_RETURN
#define DBUS_MESSAGE_TYPE_METHOD_RETURN
Message type of a method return message, see dbus_message_get_type()
Definition: dbus-protocol.h:236
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Definition: dbus-internals.h:163
_dbus_header_have_message_untrusted
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,...
Definition: dbus-marshal-header.c:677
_dbus_string_set_length
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:802
_dbus_header_get_field_raw
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.
Definition: dbus-marshal-header.c:1405
DBUS_PATH_LOCAL
#define DBUS_PATH_LOCAL
The object path used in local/in-process-generated messages.
Definition: dbus-shared.h:82
_dbus_marshal_byteswap
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.
Definition: dbus-marshal-byteswap.c:222
FIELDS_ARRAY_SIGNATURE_OFFSET
#define FIELDS_ARRAY_SIGNATURE_OFFSET
Offset from start of _dbus_header_signature_str to the signature of the fields array.
Definition: dbus-marshal-header.c:47
EXPECTED_TYPE_OF_FIELD
#define EXPECTED_TYPE_OF_FIELD(field)
Macro to look up the correct type for a field.
Definition: dbus-marshal-header.c:94
_dbus_header_free
void _dbus_header_free(DBusHeader *header)
Frees a header.
Definition: dbus-marshal-header.c:480
_dbus_validate_member
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.
Definition: dbus-marshal-validate.c:1004
_dbus_type_writer_write_basic
dbus_bool_t _dbus_type_writer_write_basic(DBusTypeWriter *writer, int type, const void *value)
Writes out a basic type.
Definition: dbus-marshal-recursive.c:2312
_dbus_validate_error_name
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.
Definition: dbus-marshal-validate.c:1065
DBUS_HEADER_FIELD_ERROR_NAME
#define DBUS_HEADER_FIELD_ERROR_NAME
Header field code for an error name (found in DBUS_MESSAGE_TYPE_ERROR messages).
Definition: dbus-protocol.h:280
DBUS_INTERFACE_LOCAL
#define DBUS_INTERFACE_LOCAL
This is a special interface whose methods can only be invoked by the local implementation (messages f...
Definition: dbus-shared.h:105
_dbus_header_get_field_basic
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.
Definition: dbus-marshal-header.c:1364
DBUS_MESSAGE_TYPE_INVALID
#define DBUS_MESSAGE_TYPE_INVALID
This value is never a valid message type, see dbus_message_get_type()
Definition: dbus-protocol.h:232
DBUS_VALIDITY_UNKNOWN_OOM_ERROR
@ DBUS_VALIDITY_UNKNOWN_OOM_ERROR
can't determine validity due to OOM
Definition: dbus-marshal-validate.h:52
FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET
#define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET
Offset from start of _dbus_header_signature_str to the signature of an element of the fields array.
Definition: dbus-marshal-header.c:49
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition: dbus-internals.h:152
TYPE_OFFSET
#define TYPE_OFFSET
Offset to type from start of header.
Definition: dbus-marshal-header.c:55
_dbus_marshal_set_uint32
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 ...
Definition: dbus-marshal-basic.c:257
_dbus_validate_interface
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.
Definition: dbus-marshal-validate.c:928
DBUS_TYPE_OBJECT_PATH
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
Definition: dbus-protocol.h:106
DBUS_TYPE_VARIANT
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
Definition: dbus-protocol.h:124
_dbus_header_byteswap
void _dbus_header_byteswap(DBusHeader *header, int new_order)
Swaps the header into the given order if required.
Definition: dbus-marshal-header.c:1509
DBusHeader::fields
DBusHeaderField fields[DBUS_HEADER_FIELD_LAST+1]
Track the location of each field in header.
Definition: dbus-marshal-header.h:54
DBUS_HEADER_FIELD_MEMBER
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
Definition: dbus-protocol.h:276
_dbus_type_writer_unrecurse
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...
Definition: dbus-marshal-recursive.c:2180
_dbus_string_equal_substring
dbus_bool_t _dbus_string_equal_substring(const DBusString *a, int a_start, int a_len, const DBusString *b, int b_start)
Tests two sub-parts of two DBusString for equality.
Definition: dbus-string.c:2104
_DBUS_STRING_DEFINE_STATIC
_DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE)
Static DBusString containing the signature of a message header.
_dbus_string_align_length
dbus_bool_t _dbus_string_align_length(DBusString *str, int alignment)
Align the length of a string to a specific alignment (typically 4 or 8) by appending nul bytes to the...
Definition: dbus-string.c:883
_dbus_type_reader_recurse
void _dbus_type_reader_recurse(DBusTypeReader *reader, DBusTypeReader *sub)
Initialize a new reader pointing to the first type and corresponding value that's a child of the curr...
Definition: dbus-marshal-recursive.c:989
DBUS_HEADER_FIELD_UNIX_FDS
#define DBUS_HEADER_FIELD_UNIX_FDS
Header field code for the number of unix file descriptors associated with this message.
Definition: dbus-protocol.h:302
HEADER_END_BEFORE_PADDING
#define HEADER_END_BEFORE_PADDING(header)
Compute the end of the header, ignoring padding.
Definition: dbus-marshal-header.c:127
DBUS_HEADER_FIELD_REPLY_SERIAL
#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...
Definition: dbus-protocol.h:284
_dbus_string_copy_len
dbus_bool_t _dbus_string_copy_len(const DBusString *source, int start, int len, DBusString *dest, int insert_at)
Like _dbus_string_copy(), but can copy a segment from the middle of the source string.
Definition: dbus-string.c:1375
_dbus_header_reinit
void _dbus_header_reinit(DBusHeader *header)
Re-initializes a header that was previously initialized and never freed.
Definition: dbus-marshal-header.c:447
DBUS_TYPE_UINT32
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
_dbus_header_create
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.
Definition: dbus-marshal-header.c:532
DBUS_HEADER_FIELD_DESTINATION
#define DBUS_HEADER_FIELD_DESTINATION
Header field code for the destination bus name of a message.
Definition: dbus-protocol.h:288
DBusTypeWriter
The type writer is an iterator for writing to a block of values.
Definition: dbus-marshal-recursive.h:65
VERSION_OFFSET
#define VERSION_OFFSET
Offset to version from start of header.
Definition: dbus-marshal-header.c:59
_dbus_string_shorten
void _dbus_string_shorten(DBusString *str, int length_to_remove)
Makes a string shorter by the given number of bytes.
Definition: dbus-string.c:780
_dbus_header_set_field_basic
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.
Definition: dbus-marshal-header.c:1286
DBUS_HEADER_FIELD_INVALID
#define DBUS_HEADER_FIELD_INVALID
Not equal to any valid header field code.
Definition: dbus-protocol.h:266
_dbus_header_init
dbus_bool_t _dbus_header_init(DBusHeader *header)
Initializes a header, but doesn't prepare it for use; to make the header valid, you have to call _dbu...
Definition: dbus-marshal-header.c:464
_dbus_string_init_const_len
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_INT32_MAX
#define _DBUS_INT32_MAX
Maximum value of type "int32".
Definition: dbus-internals.h:260
dbus_bool_t
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
DBusValidity
DBusValidity
This is primarily used in unit testing, so we can verify that each invalid message is invalid for the...
Definition: dbus-marshal-validate.h:50
NULL
#define NULL
A null pointer, defined appropriately for C or C++.