D-Bus 1.10.18

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;
73 } HeaderFieldType;
74
75 static const HeaderFieldType
76 _dbus_header_field_types[DBUS_HEADER_FIELD_LAST+1] = {
77 { DBUS_HEADER_FIELD_INVALID, DBUS_TYPE_INVALID },
78 { DBUS_HEADER_FIELD_PATH, DBUS_TYPE_OBJECT_PATH },
79 { DBUS_HEADER_FIELD_INTERFACE, DBUS_TYPE_STRING },
80 { DBUS_HEADER_FIELD_MEMBER, DBUS_TYPE_STRING },
81 { DBUS_HEADER_FIELD_ERROR_NAME, DBUS_TYPE_STRING },
82 { DBUS_HEADER_FIELD_REPLY_SERIAL, DBUS_TYPE_UINT32 },
83 { DBUS_HEADER_FIELD_DESTINATION, DBUS_TYPE_STRING },
84 { DBUS_HEADER_FIELD_SENDER, DBUS_TYPE_STRING },
85 { DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE },
86 { DBUS_HEADER_FIELD_UNIX_FDS, DBUS_TYPE_UINT32 }
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 {
97 _dbus_assert (header->padding <= MAX_POSSIBLE_HEADER_PADDING);
98
99 if (!_dbus_string_lengthen (&header->data,
100 MAX_POSSIBLE_HEADER_PADDING - header->padding))
101 return FALSE;
102 header->padding = MAX_POSSIBLE_HEADER_PADDING;
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
174 _dbus_header_get_byte_order (const DBusHeader *header)
175 {
176 _dbus_assert (_dbus_string_get_length (&header->data) > BYTE_ORDER_OFFSET);
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,
201 _dbus_header_get_byte_order (header),
202 &_dbus_header_signature_str,
203 FIELDS_ARRAY_SIGNATURE_OFFSET,
204 &header->data,
205 FIELDS_ARRAY_LENGTH_OFFSET);
206
207 _dbus_type_reader_recurse (&reader, &array);
208
209 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
210 {
211 DBusTypeReader sub;
212 DBusTypeReader variant;
213 unsigned char field_code;
214
215 _dbus_type_reader_recurse (&array, &sub);
216
217 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
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
226 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_VARIANT);
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 {
247 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
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 {
270 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
271
272 return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
273 }
274
284 static dbus_bool_t
285 write_basic_field (DBusTypeWriter *writer,
286 int field,
287 int type,
288 const void *value)
289 {
290 DBusTypeWriter sub;
291 DBusTypeWriter variant;
292 int start;
293 int padding;
294 unsigned char field_byte;
295 DBusString contained_type;
296 char buf[2];
297
298 start = writer->value_pos;
299 padding = _dbus_string_get_length (writer->value_str) - start;
300
301 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
302 NULL, 0, &sub))
303 goto append_failed;
304
305 field_byte = field;
306 if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE,
307 &field_byte))
308 goto append_failed;
309
310 buf[0] = type;
311 buf[1] = '\0';
312 _dbus_string_init_const_len (&contained_type, buf, 1);
313
314 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT,
315 &contained_type, 0, &variant))
316 goto append_failed;
317
318 if (!_dbus_type_writer_write_basic (&variant, type, value))
319 goto append_failed;
320
321 if (!_dbus_type_writer_unrecurse (&sub, &variant))
322 goto append_failed;
323
324 if (!_dbus_type_writer_unrecurse (writer, &sub))
325 goto append_failed;
326
327 return TRUE;
328
329 append_failed:
330 _dbus_string_delete (writer->value_str,
331 start,
332 _dbus_string_get_length (writer->value_str) - start - padding);
333 return FALSE;
334 }
335
346 static dbus_bool_t
347 set_basic_field (DBusTypeReader *reader,
348 int field,
349 int type,
350 const void *value,
351 const DBusTypeReader *realign_root)
352 {
353 DBusTypeReader sub;
354 DBusTypeReader variant;
355
356 _dbus_type_reader_recurse (reader, &sub);
357
358 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
359 #ifndef DBUS_DISABLE_ASSERT
360 {
361 unsigned char v_BYTE;
362 _dbus_type_reader_read_basic (&sub, &v_BYTE);
363 _dbus_assert (((int) v_BYTE) == field);
364 }
365 #endif
366
367 if (!_dbus_type_reader_next (&sub))
368 _dbus_assert_not_reached ("no variant field?");
369
370 _dbus_type_reader_recurse (&sub, &variant);
371 _dbus_assert (_dbus_type_reader_get_current_type (&variant) == type);
372
373 if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
374 return FALSE;
375
376 return TRUE;
377 }
378
385 int
386 _dbus_header_get_message_type (DBusHeader *header)
387 {
388 int type;
389
390 type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
391 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
392
393 return type;
394 }
395
403 void
404 _dbus_header_set_serial (DBusHeader *header,
405 dbus_uint32_t serial)
406 {
407 /* we use this function to set the serial on outgoing
408 * messages, and to reset the serial in dbus_message_copy;
409 * this assertion should catch a double-set on outgoing.
410 */
411 _dbus_assert (_dbus_header_get_serial (header) == 0 ||
412 serial == 0);
413
414 _dbus_marshal_set_uint32 (&header->data,
415 SERIAL_OFFSET,
416 serial,
417 _dbus_header_get_byte_order (header));
418 }
419
426 dbus_uint32_t
427 _dbus_header_get_serial (DBusHeader *header)
428 {
429 return _dbus_marshal_read_uint32 (&header->data,
430 SERIAL_OFFSET,
431 _dbus_header_get_byte_order (header),
432 NULL);
433 }
434
442 void
443 _dbus_header_reinit (DBusHeader *header)
444 {
445 _dbus_string_set_length (&header->data, 0);
446
447 header->padding = 0;
448
449 _dbus_header_cache_invalidate_all (header);
450 }
451
459 dbus_bool_t
460 _dbus_header_init (DBusHeader *header)
461 {
462 if (!_dbus_string_init_preallocated (&header->data, 32))
463 return FALSE;
464
465 _dbus_header_reinit (header);
466
467 return TRUE;
468 }
469
475 void
476 _dbus_header_free (DBusHeader *header)
477 {
478 _dbus_string_free (&header->data);
479 }
480
489 dbus_bool_t
490 _dbus_header_copy (const DBusHeader *header,
491 DBusHeader *dest)
492 {
493 *dest = *header;
494
495 if (!_dbus_string_init_preallocated (&dest->data,
496 _dbus_string_get_length (&header->data)))
497 return FALSE;
498
499 if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
500 {
501 _dbus_string_free (&dest->data);
502 return FALSE;
503 }
504
505 /* Reset the serial */
506 _dbus_header_set_serial (dest, 0);
507
508 return TRUE;
509 }
510
527 dbus_bool_t
528 _dbus_header_create (DBusHeader *header,
529 int byte_order,
530 int message_type,
531 const char *destination,
532 const char *path,
533 const char *interface,
534 const char *member,
535 const char *error_name)
536 {
537 unsigned char v_BYTE;
538 dbus_uint32_t v_UINT32;
539 DBusTypeWriter writer;
540 DBusTypeWriter array;
541
542 _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
543 byte_order == DBUS_BIG_ENDIAN);
544 _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
545 (error_name) ||
546 !(interface || member || error_name));
547 _dbus_assert (_dbus_string_get_length (&header->data) == 0);
548
549 if (!reserve_header_padding (header))
550 return FALSE;
551
552 _dbus_type_writer_init_values_only (&writer, byte_order,
553 &_dbus_header_signature_str, 0,
554 &header->data,
555 HEADER_END_BEFORE_PADDING (header));
556
557 v_BYTE = byte_order;
558 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
559 &v_BYTE))
560 goto oom;
561
562 v_BYTE = message_type;
563 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
564 &v_BYTE))
565 goto oom;
566
567 v_BYTE = 0; /* flags */
568 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
569 &v_BYTE))
570 goto oom;
571
572 v_BYTE = DBUS_MAJOR_PROTOCOL_VERSION;
573 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
574 &v_BYTE))
575 goto oom;
576
577 v_UINT32 = 0; /* body length */
578 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
579 &v_UINT32))
580 goto oom;
581
582 v_UINT32 = 0; /* serial */
583 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
584 &v_UINT32))
585 goto oom;
586
587 if (!_dbus_type_writer_recurse (&writer, DBUS_TYPE_ARRAY,
588 &_dbus_header_signature_str,
589 FIELDS_ARRAY_SIGNATURE_OFFSET,
590 &array))
591 goto oom;
592
593 /* Marshal all the fields (Marshall Fields?) */
594
595 if (path != NULL)
596 {
597 if (!write_basic_field (&array,
598 DBUS_HEADER_FIELD_PATH,
599 DBUS_TYPE_OBJECT_PATH,
600 &path))
601 goto oom;
602 }
603
604 if (destination != NULL)
605 {
606 if (!write_basic_field (&array,
607 DBUS_HEADER_FIELD_DESTINATION,
608 DBUS_TYPE_STRING,
609 &destination))
610 goto oom;
611 }
612
613 if (interface != NULL)
614 {
615 if (!write_basic_field (&array,
616 DBUS_HEADER_FIELD_INTERFACE,
617 DBUS_TYPE_STRING,
618 &interface))
619 goto oom;
620 }
621
622 if (member != NULL)
623 {
624 if (!write_basic_field (&array,
625 DBUS_HEADER_FIELD_MEMBER,
626 DBUS_TYPE_STRING,
627 &member))
628 goto oom;
629 }
630
631 if (error_name != NULL)
632 {
633 if (!write_basic_field (&array,
634 DBUS_HEADER_FIELD_ERROR_NAME,
635 DBUS_TYPE_STRING,
636 &error_name))
637 goto oom;
638 }
639
640 if (!_dbus_type_writer_unrecurse (&writer, &array))
641 goto oom;
642
643 correct_header_padding (header);
644
645 return TRUE;
646
647 oom:
648 _dbus_string_delete (&header->data, 0,
649 _dbus_string_get_length (&header->data) - header->padding);
650 correct_header_padding (header);
651
652 return FALSE;
653 }
654
672 dbus_bool_t
673 _dbus_header_have_message_untrusted (int max_message_length,
674 DBusValidity *validity,
675 int *byte_order,
676 int *fields_array_len,
677 int *header_len,
678 int *body_len,
679 const DBusString *str,
680 int start,
681 int len)
682
683 {
684 dbus_uint32_t header_len_unsigned;
685 dbus_uint32_t fields_array_len_unsigned;
686 dbus_uint32_t body_len_unsigned;
687
688 _dbus_assert (start >= 0);
689 _dbus_assert (start < _DBUS_INT32_MAX / 2);
690 _dbus_assert (len >= 0);
691
692 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
693
694 *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
695
696 if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
697 {
698 *validity = DBUS_INVALID_BAD_BYTE_ORDER;
699 return FALSE;
700 }
701
702 _dbus_assert (FIELDS_ARRAY_LENGTH_OFFSET + 4 <= len);
703 fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
704 *byte_order, NULL);
705
706 if (fields_array_len_unsigned > (unsigned) max_message_length)
707 {
708 *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
709 return FALSE;
710 }
711
712 _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
713 body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
714 *byte_order, NULL);
715
716 if (body_len_unsigned > (unsigned) max_message_length)
717 {
718 *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
719 return FALSE;
720 }
721
722 header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
723 header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
724
725 /* overflow should be impossible since the lengths aren't allowed to
726 * be huge.
727 */
728 _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2);
729 if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
730 {
731 *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
732 return FALSE;
733 }
734
735 _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX);
736 _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX);
737 _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX);
738
739 *body_len = body_len_unsigned;
740 *fields_array_len = fields_array_len_unsigned;
741 *header_len = header_len_unsigned;
742
743 *validity = DBUS_VALID;
744
745 _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
746 len, body_len_unsigned, header_len_unsigned,
747 body_len_unsigned + header_len_unsigned);
748
749 return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
750 }
751
752 static DBusValidity
753 check_mandatory_fields (DBusHeader *header)
754 {
755 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
756
757 switch (_dbus_header_get_message_type (header))
758 {
759 case DBUS_MESSAGE_TYPE_SIGNAL:
760 REQUIRE_FIELD (INTERFACE);
761 /* FALL THRU - signals also require the path and member */
762 case DBUS_MESSAGE_TYPE_METHOD_CALL:
763 REQUIRE_FIELD (PATH);
764 REQUIRE_FIELD (MEMBER);
765 break;
766 case DBUS_MESSAGE_TYPE_ERROR:
767 REQUIRE_FIELD (ERROR_NAME);
768 REQUIRE_FIELD (REPLY_SERIAL);
769 break;
770 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
771 REQUIRE_FIELD (REPLY_SERIAL);
772 break;
773 default:
774 /* other message types allowed but ignored */
775 break;
776 }
777
778 return DBUS_VALID;
779 }
780
781 static DBusValidity
782 load_and_validate_field (DBusHeader *header,
783 int field,
784 DBusTypeReader *variant_reader)
785 {
786 int type;
787 int expected_type;
788 const DBusString *value_str;
789 int value_pos;
790 int str_data_pos;
791 dbus_uint32_t v_UINT32;
792 int bad_string_code;
793 dbus_bool_t (* string_validation_func) (const DBusString *str,
794 int start, int len);
795
796 /* Supposed to have been checked already */
797 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
798 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
799
800 /* Before we can cache a field, we need to know it has the right type */
801 type = _dbus_type_reader_get_current_type (variant_reader);
802
803 _dbus_assert (_dbus_header_field_types[field].code == field);
804
805 expected_type = EXPECTED_TYPE_OF_FIELD (field);
806 if (type != expected_type)
807 {
808 _dbus_verbose ("Field %d should have type %d but has %d\n",
809 field, expected_type, type);
810 return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
811 }
812
813 /* If the field was provided twice, we aren't happy */
814 if (header->fields[field].value_pos >= 0)
815 {
816 _dbus_verbose ("Header field %d seen a second time\n", field);
817 return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
818 }
819
820 /* Now we can cache and look at the field content */
821 _dbus_verbose ("initially caching field %d\n", field);
822 _dbus_header_cache_one (header, field, variant_reader);
823
824 string_validation_func = NULL;
825
826 /* make compiler happy that all this is initialized */
827 v_UINT32 = 0;
828 value_str = NULL;
829 value_pos = -1;
830 str_data_pos = -1;
831 bad_string_code = DBUS_VALID;
832
833 if (expected_type == DBUS_TYPE_UINT32)
834 {
835 _dbus_header_get_field_basic (header, field, expected_type,
836 &v_UINT32);
837 }
838 else if (expected_type == DBUS_TYPE_STRING ||
839 expected_type == DBUS_TYPE_OBJECT_PATH ||
840 expected_type == DBUS_TYPE_SIGNATURE)
841 {
842 _dbus_header_get_field_raw (header, field,
843 &value_str, &value_pos);
844 str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
845 }
846 else
847 {
848 _dbus_assert_not_reached ("none of the known fields should have this type");
849 }
850
851 switch (field)
852 {
853 case DBUS_HEADER_FIELD_DESTINATION:
854 string_validation_func = _dbus_validate_bus_name;
855 bad_string_code = DBUS_INVALID_BAD_DESTINATION;
856 break;
857 case DBUS_HEADER_FIELD_INTERFACE:
858 string_validation_func = _dbus_validate_interface;
859 bad_string_code = DBUS_INVALID_BAD_INTERFACE;
860
861 if (_dbus_string_equal_substring (&_dbus_local_interface_str,
862 0,
863 _dbus_string_get_length (&_dbus_local_interface_str),
864 value_str, str_data_pos))
865 {
866 _dbus_verbose ("Message is on the local interface\n");
867 return DBUS_INVALID_USES_LOCAL_INTERFACE;
868 }
869 break;
870
871 case DBUS_HEADER_FIELD_MEMBER:
872 string_validation_func = _dbus_validate_member;
873 bad_string_code = DBUS_INVALID_BAD_MEMBER;
874 break;
875
876 case DBUS_HEADER_FIELD_ERROR_NAME:
877 string_validation_func = _dbus_validate_error_name;
878 bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
879 break;
880
881 case DBUS_HEADER_FIELD_SENDER:
882 string_validation_func = _dbus_validate_bus_name;
883 bad_string_code = DBUS_INVALID_BAD_SENDER;
884 break;
885
886 case DBUS_HEADER_FIELD_PATH:
887 /* OBJECT_PATH was validated generically due to its type */
888 string_validation_func = NULL;
889
890 if (_dbus_string_equal_substring (&_dbus_local_path_str,
891 0,
892 _dbus_string_get_length (&_dbus_local_path_str),
893 value_str, str_data_pos))
894 {
895 _dbus_verbose ("Message is from the local path\n");
896 return DBUS_INVALID_USES_LOCAL_PATH;
897 }
898 break;
899
900 case DBUS_HEADER_FIELD_REPLY_SERIAL:
901 /* Can't be 0 */
902 if (v_UINT32 == 0)
903 {
904 return DBUS_INVALID_BAD_SERIAL;
905 }
906 break;
907
908 case DBUS_HEADER_FIELD_UNIX_FDS:
909 /* Every value makes sense */
910 break;
911
912 case DBUS_HEADER_FIELD_SIGNATURE:
913 /* SIGNATURE validated generically due to its type */
914 string_validation_func = NULL;
915 break;
916
917 default:
918 _dbus_assert_not_reached ("unknown field shouldn't be seen here");
919 break;
920 }
921
922 if (string_validation_func)
923 {
924 dbus_uint32_t len;
925
926 _dbus_assert (bad_string_code != DBUS_VALID);
927
928 len = _dbus_marshal_read_uint32 (value_str, value_pos,
929 _dbus_header_get_byte_order (header),
930 NULL);
931
932 #if 0
933 _dbus_verbose ("Validating string header field; code %d if fails\n",
934 bad_string_code);
935 #endif
936 if (!(*string_validation_func) (value_str, str_data_pos, len))
937 return bad_string_code;
938 }
939
940 return DBUS_VALID;
941 }
942
969 dbus_bool_t
970 _dbus_header_load (DBusHeader *header,
971 DBusValidationMode mode,
972 DBusValidity *validity,
973 int byte_order,
974 int fields_array_len,
975 int header_len,
976 int body_len,
977 const DBusString *str,
978 int start,
979 int len)
980 {
981 int leftover;
982 DBusValidity v;
983 DBusTypeReader reader;
984 DBusTypeReader array_reader;
985 unsigned char v_byte;
986 dbus_uint32_t v_uint32;
987 dbus_uint32_t serial;
988 int padding_start;
989 int padding_len;
990 int i;
991
992 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
993 _dbus_assert (header_len <= len);
994 _dbus_assert (_dbus_string_get_length (&header->data) == 0);
995
996 if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
997 {
998 _dbus_verbose ("Failed to copy buffer into new header\n");
999 *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
1000 return FALSE;
1001 }
1002
1003 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1004 {
1005 leftover = len - header_len - body_len - start;
1006 }
1007 else
1008 {
1009 v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
1010 byte_order,
1011 &leftover,
1012 str, start, len);
1013
1014 if (v != DBUS_VALID)
1015 {
1016 *validity = v;
1017 goto invalid;
1018 }
1019 }
1020
1021 _dbus_assert (leftover < len);
1022
1023 padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
1024 padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
1025 _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
1026 _dbus_assert (start + header_len == padding_start + padding_len);
1027
1028 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1029 {
1030 if (!_dbus_string_validate_nul (str, padding_start, padding_len))
1031 {
1032 *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1033 goto invalid;
1034 }
1035 }
1036
1037 header->padding = padding_len;
1038
1039 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1040 {
1041 *validity = DBUS_VALID;
1042 return TRUE;
1043 }
1044
1045 /* We now know the data is well-formed, but we have to check that
1046 * it's valid.
1047 */
1048
1049 _dbus_type_reader_init (&reader,
1050 byte_order,
1051 &_dbus_header_signature_str, 0,
1052 str, start);
1053
1054 /* BYTE ORDER */
1055 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1056 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BYTE_ORDER_OFFSET);
1057 _dbus_type_reader_read_basic (&reader, &v_byte);
1058 _dbus_type_reader_next (&reader);
1059
1060 _dbus_assert (v_byte == byte_order);
1061
1062 /* MESSAGE TYPE */
1063 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1064 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == TYPE_OFFSET);
1065 _dbus_type_reader_read_basic (&reader, &v_byte);
1066 _dbus_type_reader_next (&reader);
1067
1068 /* unknown message types are supposed to be ignored, so only validation here is
1069 * that it isn't invalid
1070 */
1071 if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1072 {
1073 *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1074 goto invalid;
1075 }
1076
1077 /* FLAGS */
1078 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1079 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FLAGS_OFFSET);
1080 _dbus_type_reader_read_basic (&reader, &v_byte);
1081 _dbus_type_reader_next (&reader);
1082
1083 /* unknown flags should be ignored */
1084
1085 /* PROTOCOL VERSION */
1086 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1087 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == VERSION_OFFSET);
1088 _dbus_type_reader_read_basic (&reader, &v_byte);
1089 _dbus_type_reader_next (&reader);
1090
1091 if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1092 {
1093 *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1094 goto invalid;
1095 }
1096
1097 /* BODY LENGTH */
1098 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
1099 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BODY_LENGTH_OFFSET);
1100 _dbus_type_reader_read_basic (&reader, &v_uint32);
1101 _dbus_type_reader_next (&reader);
1102
1103 _dbus_assert (body_len == (signed) v_uint32);
1104
1105 /* SERIAL */
1106 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
1107 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == SERIAL_OFFSET);
1108 _dbus_type_reader_read_basic (&reader, &serial);
1109 _dbus_type_reader_next (&reader);
1110
1111 if (serial == 0)
1112 {
1113 *validity = DBUS_INVALID_BAD_SERIAL;
1114 goto invalid;
1115 }
1116
1117 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_ARRAY);
1118 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FIELDS_ARRAY_LENGTH_OFFSET);
1119
1120 _dbus_type_reader_recurse (&reader, &array_reader);
1121 while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1122 {
1123 DBusTypeReader struct_reader;
1124 DBusTypeReader variant_reader;
1125 unsigned char field_code;
1126
1127 _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT);
1128
1129 _dbus_type_reader_recurse (&array_reader, &struct_reader);
1130
1131 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_BYTE);
1132 _dbus_type_reader_read_basic (&struct_reader, &field_code);
1133 _dbus_type_reader_next (&struct_reader);
1134
1135 if (field_code == DBUS_HEADER_FIELD_INVALID)
1136 {
1137 _dbus_verbose ("invalid header field code\n");
1138 *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1139 goto invalid;
1140 }
1141
1142 if (field_code > DBUS_HEADER_FIELD_LAST)
1143 {
1144 _dbus_verbose ("unknown header field code %d, skipping\n",
1145 field_code);
1146 goto next_field;
1147 }
1148
1149 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT);
1150 _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1151
1152 v = load_and_validate_field (header, field_code, &variant_reader);
1153 if (v != DBUS_VALID)
1154 {
1155 _dbus_verbose ("Field %d was invalid\n", field_code);
1156 *validity = v;
1157 goto invalid;
1158 }
1159
1160 next_field:
1161 _dbus_type_reader_next (&array_reader);
1162 }
1163
1164 /* Anything we didn't fill in is now known not to exist */
1165 i = 0;
1166 while (i <= DBUS_HEADER_FIELD_LAST)
1167 {
1168 if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1169 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1170 ++i;
1171 }
1172
1173 v = check_mandatory_fields (header);
1174 if (v != DBUS_VALID)
1175 {
1176 _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1177 *validity = v;
1178 goto invalid;
1179 }
1180
1181 *validity = DBUS_VALID;
1182 return TRUE;
1183
1184 invalid:
1185 _dbus_string_set_length (&header->data, 0);
1186 return FALSE;
1187 }
1188
1195 void
1196 _dbus_header_update_lengths (DBusHeader *header,
1197 int body_len)
1198 {
1199 _dbus_marshal_set_uint32 (&header->data,
1200 BODY_LENGTH_OFFSET,
1201 body_len,
1202 _dbus_header_get_byte_order (header));
1203 }
1204
1218 static dbus_bool_t
1219 find_field_for_modification (DBusHeader *header,
1220 int field,
1221 DBusTypeReader *reader,
1222 DBusTypeReader *realign_root)
1223 {
1224 dbus_bool_t retval;
1225
1226 retval = FALSE;
1227
1228 _dbus_type_reader_init (realign_root,
1229 _dbus_header_get_byte_order (header),
1230 &_dbus_header_signature_str,
1231 FIELDS_ARRAY_SIGNATURE_OFFSET,
1232 &header->data,
1233 FIELDS_ARRAY_LENGTH_OFFSET);
1234
1235 _dbus_type_reader_recurse (realign_root, reader);
1236
1237 while (_dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID)
1238 {
1239 DBusTypeReader sub;
1240 unsigned char field_code;
1241
1242 _dbus_type_reader_recurse (reader, &sub);
1243
1244 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
1245 _dbus_type_reader_read_basic (&sub, &field_code);
1246
1247 if (field_code == (unsigned) field)
1248 {
1249 _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_STRUCT);
1250 retval = TRUE;
1251 goto done;
1252 }
1253
1254 _dbus_type_reader_next (reader);
1255 }
1256
1257 done:
1258 return retval;
1259 }
1260
1272 dbus_bool_t
1273 _dbus_header_set_field_basic (DBusHeader *header,
1274 int field,
1275 int type,
1276 const void *value)
1277 {
1278 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
1279
1280 if (!reserve_header_padding (header))
1281 return FALSE;
1282
1283 /* If the field exists we set, otherwise we append */
1284 if (_dbus_header_cache_check (header, field))
1285 {
1286 DBusTypeReader reader;
1287 DBusTypeReader realign_root;
1288
1289 if (!find_field_for_modification (header, field,
1290 &reader, &realign_root))
1291 _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1292
1293 if (!set_basic_field (&reader, field, type, value, &realign_root))
1294 return FALSE;
1295 }
1296 else
1297 {
1298 DBusTypeWriter writer;
1299 DBusTypeWriter array;
1300
1301 _dbus_type_writer_init_values_only (&writer,
1302 _dbus_header_get_byte_order (header),
1303 &_dbus_header_signature_str,
1304 FIELDS_ARRAY_SIGNATURE_OFFSET,
1305 &header->data,
1306 FIELDS_ARRAY_LENGTH_OFFSET);
1307
1308 /* recurse into array without creating a new length, and jump to
1309 * end of array.
1310 */
1311 if (!_dbus_type_writer_append_array (&writer,
1312 &_dbus_header_signature_str,
1313 FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET,
1314 &array))
1315 _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1316
1317 _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1318 _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1319 _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1320
1321 if (!write_basic_field (&array,
1322 field, type, value))
1323 return FALSE;
1324
1325 if (!_dbus_type_writer_unrecurse (&writer, &array))
1326 _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1327 }
1328
1329 correct_header_padding (header);
1330
1331 /* We could be smarter about this (only invalidate fields after the
1332 * one we modified, or even only if the one we modified changed
1333 * length). But this hack is a start.
1334 */
1335 _dbus_header_cache_invalidate_all (header);
1336
1337 return TRUE;
1338 }
1339
1350 dbus_bool_t
1351 _dbus_header_get_field_basic (DBusHeader *header,
1352 int field,
1353 int type,
1354 void *value)
1355 {
1356 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
1357 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
1358 _dbus_assert (_dbus_header_field_types[field].code == field);
1359 /* in light of this you might ask why the type is passed in;
1360 * the only rationale I can think of is so the caller has
1361 * to specify its expectation and breaks if we change it
1362 */
1363 _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1364
1365 if (!_dbus_header_cache_check (header, field))
1366 return FALSE;
1367
1368 _dbus_assert (header->fields[field].value_pos >= 0);
1369
1370 _dbus_marshal_read_basic (&header->data,
1371 header->fields[field].value_pos,
1372 type, value, _dbus_header_get_byte_order (header),
1373 NULL);
1374
1375 return TRUE;
1376 }
1377
1391 dbus_bool_t
1392 _dbus_header_get_field_raw (DBusHeader *header,
1393 int field,
1394 const DBusString **str,
1395 int *pos)
1396 {
1397 if (!_dbus_header_cache_check (header, field))
1398 return FALSE;
1399
1400 if (str)
1401 *str = &header->data;
1402 if (pos)
1403 *pos = header->fields[field].value_pos;
1404
1405 return TRUE;
1406 }
1407
1415 dbus_bool_t
1416 _dbus_header_delete_field (DBusHeader *header,
1417 int field)
1418 {
1419 DBusTypeReader reader;
1420 DBusTypeReader realign_root;
1421
1422 if (_dbus_header_cache_known_nonexistent (header, field))
1423 return TRUE; /* nothing to do */
1424
1425 /* Scan to the field we want, delete and realign, reappend
1426 * padding. Field may turn out not to exist.
1427 */
1428 if (!find_field_for_modification (header, field,
1429 &reader, &realign_root))
1430 return TRUE; /* nothing to do */
1431
1432 if (!reserve_header_padding (header))
1433 return FALSE;
1434
1435 if (!_dbus_type_reader_delete (&reader,
1436 &realign_root))
1437 return FALSE;
1438
1439 correct_header_padding (header);
1440
1441 _dbus_header_cache_invalidate_all (header);
1442
1443 _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1444
1445 return TRUE;
1446 }
1447
1456 void
1457 _dbus_header_toggle_flag (DBusHeader *header,
1458 dbus_uint32_t flag,
1459 dbus_bool_t value)
1460 {
1461 unsigned char *flags_p;
1462
1463 flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1);
1464
1465 if (value)
1466 *flags_p |= flag;
1467 else
1468 *flags_p &= ~flag;
1469 }
1470
1478 dbus_bool_t
1479 _dbus_header_get_flag (DBusHeader *header,
1480 dbus_uint32_t flag)
1481 {
1482 const unsigned char *flags_p;
1483
1484 flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1);
1485
1486 return (*flags_p & flag) != 0;
1487 }
1488
1495 void
1496 _dbus_header_byteswap (DBusHeader *header,
1497 int new_order)
1498 {
1499 char byte_order;
1500
1501 byte_order = _dbus_header_get_byte_order (header);
1502
1503 if (byte_order == new_order)
1504 return;
1505
1506 _dbus_marshal_byteswap (&_dbus_header_signature_str,
1507 0, byte_order,
1508 new_order,
1509 &header->data, 0);
1510
1511 _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order);
1512 }
1513
_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:703
dbus_uint32_t
unsigned int dbus_uint32_t
A 32-bit unsigned integer on all platforms.
Definition: dbus-arch-deps.h:43
DBUS_HEADER_FIELD_INVALID
#define DBUS_HEADER_FIELD_INVALID
Not equal to any valid header field code.
Definition: dbus-protocol.h:266
NULL
#define NULL
A null pointer, defined appropriately for C or C++.
_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:970
_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:490
_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:253
_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
DBusTypeWriter
The type writer is an iterator for writing to a block of values.
Definition: dbus-marshal-recursive.h:64
_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&#39;s a child of the curr...
Definition: dbus-marshal-recursive.c:989
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_TYPE_STRUCT
#define DBUS_TYPE_STRUCT
STRUCT and DICT_ENTRY are sort of special since their codes can&#39;t appear in a type string...
Definition: dbus-protocol.h:136
DBusHeader::padding
dbus_uint32_t padding
bytes of alignment in header
Definition: dbus-marshal-header.h:58
DBUS_TYPE_STRING
#define DBUS_TYPE_STRING
Type code marking a UTF-8 encoded, nul-terminated Unicode string.
Definition: dbus-protocol.h:102
_dbus_header_get_serial
dbus_uint32_t _dbus_header_get_serial(DBusHeader *header)
See dbus_message_get_serial()
Definition: dbus-marshal-header.c:427
_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:1479
_dbus_assert
#define _dbus_assert(condition)
Aborts with an error message if the condition is false.
Definition: dbus-internals.h:148
_dbus_header_init
dbus_bool_t _dbus_header_init(DBusHeader *header)
Initializes a header, but doesn&#39;t prepare it for use; to make the header valid, you have to call _dbu...
Definition: dbus-marshal-header.c:460
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:326
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:311
DBUS_TYPE_BYTE
#define DBUS_TYPE_BYTE
Type code marking an 8-bit unsigned integer.
Definition: dbus-protocol.h:66
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_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:921
DBusHeader::data
DBusString data
Header network data, stored separately from body so we can independently realloc it.
Definition: dbus-marshal-header.h:49
_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:2311
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_string_get_data_len
char * _dbus_string_get_data_len(DBusString *str, int start, int len)
Gets a sub-portion of the raw character buffer from the string.
Definition: dbus-string.c:490
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
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:90
_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
DBusValidationMode
DBusValidationMode
This is used rather than a bool for high visibility.
Definition: dbus-marshal-validate.h:36
_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&#39;s copied to the d...
Definition: dbus-string.c:1283
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
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:49
_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:997
DBusTypeWriter::value_str
DBusString * value_str
where to write values
Definition: dbus-marshal-recursive.h:76
VERSION_OFFSET
#define VERSION_OFFSET
Offset to version from start of header.
Definition: dbus-marshal-header.c:59
DBUS_PATH_LOCAL
#define DBUS_PATH_LOCAL
The object path used in local/in-process-generated messages.
Definition: dbus-shared.h:82
DBUS_TYPE_ARRAY
#define DBUS_TYPE_ARRAY
Type code marking a D-Bus array type.
Definition: dbus-protocol.h:120
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_MAJOR_PROTOCOL_VERSION
#define DBUS_MAJOR_PROTOCOL_VERSION
Protocol version.
Definition: dbus-protocol.h:57
_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:1058
BYTE_ORDER_OFFSET
#define BYTE_ORDER_OFFSET
Offset to byte order from start of header.
Definition: dbus-marshal-header.c:53
_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:1420
TYPE_OFFSET
#define TYPE_OFFSET
Offset to type from start of header.
Definition: dbus-marshal-header.c:55
_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:1584
_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:1363
_dbus_header_get_message_type
int _dbus_header_get_message_type(DBusHeader *header)
Gets the type of the message.
Definition: dbus-marshal-header.c:386
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
BODY_LENGTH_OFFSET
#define BODY_LENGTH_OFFSET
Offset to body length from start of header.
Definition: dbus-marshal-header.c:61
DBusString
Definition: dbus-string.h:42
_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:2179
dbus_bool_t
dbus_uint32_t dbus_bool_t
A boolean, valid values are TRUE and FALSE.
Definition: dbus-types.h:35
_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
DBusHeaderField::value_pos
int value_pos
Position of field value, or -1/-2.
Definition: dbus-marshal-header.h:41
SERIAL_OFFSET
#define SERIAL_OFFSET
Offset to client serial from start of header.
Definition: dbus-marshal-header.c:63
_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:1351
DBUS_VALIDITY_UNKNOWN_OOM_ERROR
can&#39;t determine validity due to OOM
Definition: dbus-marshal-validate.h:52
_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_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
_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:2143
_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:492
_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:1054
_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:1496
_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, check whether the data is long enough to contain the entire message (assuming the claimed lengths are accurate).
Definition: dbus-marshal-header.c:673
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
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
DBUS_BIG_ENDIAN
#define DBUS_BIG_ENDIAN
Code marking MSB-first byte order in the wire protocol.
Definition: dbus-protocol.h:54
DBUS_TYPE_SIGNATURE
#define DBUS_TYPE_SIGNATURE
Type code marking a D-Bus type signature.
Definition: dbus-protocol.h:110
_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:1187
_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_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_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
FIRST_FIELD_OFFSET
#define FIRST_FIELD_OFFSET
Offset to first field in header.
Definition: dbus-marshal-header.c:67
DBUS_TYPE_VARIANT
#define DBUS_TYPE_VARIANT
Type code marking a D-Bus variant type.
Definition: dbus-protocol.h:124
HEADER_END_BEFORE_PADDING
#define HEADER_END_BEFORE_PADDING(header)
Compute the end of the header, ignoring padding.
Definition: dbus-marshal-header.c:123
DBUS_TYPE_UINT32
#define DBUS_TYPE_UINT32
Type code marking a 32-bit unsigned integer.
Definition: dbus-protocol.h:86
_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:443
DBUS_VALID
the data is valid
Definition: dbus-marshal-validate.h:56
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
_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:1416
HeaderFieldType::type
unsigned char type
the value type
Definition: dbus-marshal-header.c:72
MAX_POSSIBLE_HEADER_PADDING
#define MAX_POSSIBLE_HEADER_PADDING
The most padding we could ever need for a header.
Definition: dbus-marshal-header.c:93
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_string_free
void _dbus_string_free(DBusString *str)
Frees a string created by _dbus_string_init().
Definition: dbus-string.c:259
DBusTypeReader
The type reader is an iterator for reading values from a block of values.
Definition: dbus-marshal-recursive.h:39
TRUE
#define TRUE
Expands to "1".
_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:1273
_dbus_assert_not_reached
#define _dbus_assert_not_reached(explanation)
Aborts with an error message if called.
Definition: dbus-internals.h:159
DBUS_HEADER_FIELD_MEMBER
#define DBUS_HEADER_FIELD_MEMBER
Header field code for a member (method or signal).
Definition: dbus-protocol.h:276
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_OBJECT_PATH
#define DBUS_TYPE_OBJECT_PATH
Type code marking a D-Bus object path.
Definition: dbus-protocol.h:106
_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:528
DBUS_TYPE_INVALID
#define DBUS_TYPE_INVALID
Type code that is never equal to a legitimate type code.
Definition: dbus-protocol.h:60
HeaderFieldType::code
unsigned char code
the field code
Definition: dbus-marshal-header.c:71
HeaderFieldType
Definition: dbus-marshal-header.c:69
DBusTypeWriter::value_pos
int value_pos
next position to write
Definition: dbus-marshal-recursive.h:77
_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_header_free
void _dbus_header_free(DBusHeader *header)
Frees a header.
Definition: dbus-marshal-header.c:476
DBusHeader::fields
DBusHeaderField fields[DBUS_HEADER_FIELD_LAST+1]
Track the location of each field in header.
Definition: dbus-marshal-header.h:54
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_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:404
_dbus_header_get_byte_order
char _dbus_header_get_byte_order(const DBusHeader *header)
Returns the header&#39;s byte order.
Definition: dbus-marshal-header.c:174
_DBUS_STRING_DEFINE_STATIC
_DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE)
Static DBusString containing the signature of a message header.
DBusTypeWriter::u
union DBusTypeWriter::@3 u
class-specific data
_DBUS_INT32_MAX
#define _DBUS_INT32_MAX
Maximum value of type "int32".
Definition: dbus-internals.h:259
_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
_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:1392
_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
FALSE
#define FALSE
Expands to "0".
DBusHeader
Message header data and some cached details of it.
Definition: dbus-marshal-header.h:47
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_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_set_length
dbus_bool_t _dbus_string_set_length(DBusString *str, int length)
Sets the length of a string.
Definition: dbus-string.c:802
FLAGS_OFFSET
#define FLAGS_OFFSET
Offset to flags from start of header.
Definition: dbus-marshal-header.c:57
_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_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_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:2109
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
_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:1457
_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:1196
_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
_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_LITTLE_ENDIAN
#define DBUS_LITTLE_ENDIAN
Code marking LSB-first byte order in the wire protocol.
Definition: dbus-protocol.h:53
_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:454