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