1 /* -*- mode: C; c-file-style: "gnu" -*- */
2 /* dbus-marshal-header.c Managing marshaling/demarshaling of message headers
4 * Copyright (C) 2005 Red Hat, Inc.
6 * Licensed under the Academic Free License version 2.1
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "dbus/dbus-shared.h"
25 #include "dbus-marshal-header.h"
26 #include "dbus-marshal-recursive.h"
27 #include "dbus-marshal-byteswap.h"
30 * @addtogroup DBusMarshal
36 /* Not thread locked, but strictly const/read-only so should be OK
38 /** Static #DBusString containing the signature of a message header */
39 _DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE);
40 /** Static #DBusString containing the local interface */
41 _DBUS_STRING_DEFINE_STATIC(_dbus_local_interface_str, DBUS_INTERFACE_LOCAL);
42 /** Static #DBusString containing the local path */
43 _DBUS_STRING_DEFINE_STATIC(_dbus_local_path_str, DBUS_PATH_LOCAL);
45 /** Offset from start of _dbus_header_signature_str to the signature of the fields array */
46 #define FIELDS_ARRAY_SIGNATURE_OFFSET 6
47 /** Offset from start of _dbus_header_signature_str to the signature of an element of the fields array */
48 #define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET 7
51 /** Offset to byte order from start of header */
52 #define BYTE_ORDER_OFFSET 0
53 /** Offset to type from start of header */
55 /** Offset to flags from start of header */
56 #define FLAGS_OFFSET 2
57 /** Offset to version from start of header */
58 #define VERSION_OFFSET 3
59 /** Offset to body length from start of header */
60 #define BODY_LENGTH_OFFSET 4
61 /** Offset to client serial from start of header */
62 #define SERIAL_OFFSET 8
63 /** Offset to fields array length from start of header */
64 #define FIELDS_ARRAY_LENGTH_OFFSET 12
65 /** Offset to first field in header */
66 #define FIRST_FIELD_OFFSET 16
74 static const HeaderFieldType
75 _dbus_header_field_types[DBUS_HEADER_FIELD_LAST+1] = {
76 { DBUS_HEADER_FIELD_INVALID, DBUS_TYPE_INVALID },
77 { DBUS_HEADER_FIELD_PATH, DBUS_TYPE_OBJECT_PATH },
78 { DBUS_HEADER_FIELD_INTERFACE, DBUS_TYPE_STRING },
79 { DBUS_HEADER_FIELD_MEMBER, DBUS_TYPE_STRING },
80 { DBUS_HEADER_FIELD_ERROR_NAME, DBUS_TYPE_STRING },
81 { DBUS_HEADER_FIELD_REPLY_SERIAL, DBUS_TYPE_UINT32 },
82 { DBUS_HEADER_FIELD_DESTINATION, DBUS_TYPE_STRING },
83 { DBUS_HEADER_FIELD_SENDER, DBUS_TYPE_STRING },
84 { DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE }
87 /** Macro to look up the correct type for a field */
88 #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type)
90 /** The most padding we could ever need for a header */
91 #define MAX_POSSIBLE_HEADER_PADDING 7
93 reserve_header_padding (DBusHeader *header)
95 _dbus_assert (header->padding <= MAX_POSSIBLE_HEADER_PADDING);
97 if (!_dbus_string_lengthen (&header->data,
98 MAX_POSSIBLE_HEADER_PADDING - header->padding))
100 header->padding = MAX_POSSIBLE_HEADER_PADDING;
105 correct_header_padding (DBusHeader *header)
109 _dbus_assert (header->padding == 7);
111 _dbus_string_shorten (&header->data, header->padding);
112 unpadded_len = _dbus_string_get_length (&header->data);
114 if (!_dbus_string_align_length (&header->data, 8))
115 _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");
117 header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
120 /** Compute the end of the header, ignoring padding */
121 #define HEADER_END_BEFORE_PADDING(header) \
122 (_dbus_string_get_length (&(header)->data) - (header)->padding)
125 * Invalidates all fields in the cache. This may be used when the
126 * cache is totally uninitialized (contains junk) so should not
127 * look at what's in there now.
129 * @param header the header
132 _dbus_header_cache_invalidate_all (DBusHeader *header)
137 while (i <= DBUS_HEADER_FIELD_LAST)
139 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN;
147 * @param header the header
148 * @param field_code the field
149 * @param variant_reader the reader for the variant in the field
152 _dbus_header_cache_one (DBusHeader *header,
154 DBusTypeReader *variant_reader)
158 variant_type = _dbus_type_reader_get_current_type (variant_reader);
160 header->fields[field_code].value_pos =
161 _dbus_type_reader_get_value_pos (variant_reader);
164 _dbus_verbose ("cached value_pos %d for field %d\n",
165 header->fields[field_code].value_pos, field_code)
170 * Revalidates the fields cache
172 * @param header the header
175 _dbus_header_cache_revalidate (DBusHeader *header)
177 DBusTypeReader array;
178 DBusTypeReader reader;
182 while (i <= DBUS_HEADER_FIELD_LAST)
184 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
188 _dbus_type_reader_init (&reader,
190 &_dbus_header_signature_str,
191 FIELDS_ARRAY_SIGNATURE_OFFSET,
193 FIELDS_ARRAY_LENGTH_OFFSET);
195 _dbus_type_reader_recurse (&reader, &array);
197 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
200 DBusTypeReader variant;
201 unsigned char field_code;
203 _dbus_type_reader_recurse (&array, &sub);
205 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
206 _dbus_type_reader_read_basic (&sub, &field_code);
208 /* Unknown fields should be ignored */
209 if (field_code > DBUS_HEADER_FIELD_LAST)
212 _dbus_type_reader_next (&sub);
214 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_VARIANT);
215 _dbus_type_reader_recurse (&sub, &variant);
217 _dbus_header_cache_one (header, field_code, &variant);
220 _dbus_type_reader_next (&array);
225 * Checks for a field, updating the cache if required.
227 * @param header the header
228 * @param field the field to check
229 * @returns #FALSE if the field doesn't exist
232 _dbus_header_cache_check (DBusHeader *header,
235 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
237 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
238 _dbus_header_cache_revalidate (header);
240 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
247 * Checks whether a field is known not to exist. It may exist
248 * even if it's not known to exist.
250 * @param header the header
251 * @param field the field to check
252 * @returns #FALSE if the field definitely doesn't exist
255 _dbus_header_cache_known_nonexistent (DBusHeader *header,
258 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
260 return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
264 * Writes a struct of { byte, variant } with the given basic type.
266 * @param writer the writer (should be ready to write a struct)
267 * @param type the type of the value
268 * @param value the value as for _dbus_marshal_set_basic()
269 * @returns #FALSE if no memory
272 write_basic_field (DBusTypeWriter *writer,
278 DBusTypeWriter variant;
281 unsigned char field_byte;
282 DBusString contained_type;
285 start = writer->value_pos;
286 padding = _dbus_string_get_length (writer->value_str) - start;
288 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
293 if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE,
299 _dbus_string_init_const_len (&contained_type, buf, 1);
301 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT,
302 &contained_type, 0, &variant))
305 if (!_dbus_type_writer_write_basic (&variant, type, value))
308 if (!_dbus_type_writer_unrecurse (&sub, &variant))
311 if (!_dbus_type_writer_unrecurse (writer, &sub))
317 _dbus_string_delete (writer->value_str,
319 _dbus_string_get_length (writer->value_str) - start - padding);
324 * Sets a struct of { byte, variant } with the given basic type.
326 * @param reader the reader (should be iterating over the array pointing at the field to set)
327 * @param type the type of the value
328 * @param value the value as for _dbus_marshal_set_basic()
329 * @param realign_root where to realign from
330 * @returns #FALSE if no memory
333 set_basic_field (DBusTypeReader *reader,
337 const DBusTypeReader *realign_root)
340 DBusTypeReader variant;
342 _dbus_type_reader_recurse (reader, &sub);
344 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
345 #ifndef DBUS_DISABLE_ASSERT
347 unsigned char v_BYTE;
348 _dbus_type_reader_read_basic (&sub, &v_BYTE);
349 _dbus_assert (((int) v_BYTE) == field);
353 if (!_dbus_type_reader_next (&sub))
354 _dbus_assert_not_reached ("no variant field?");
356 _dbus_type_reader_recurse (&sub, &variant);
357 _dbus_assert (_dbus_type_reader_get_current_type (&variant) == type);
359 if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
366 * Gets the type of the message.
368 * @param header the header
372 _dbus_header_get_message_type (DBusHeader *header)
376 type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
377 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
383 * Sets the serial number of a header. This can only be done once on
386 * @param header the header
387 * @param serial the serial
390 _dbus_header_set_serial (DBusHeader *header,
391 dbus_uint32_t serial)
393 /* we use this function to set the serial on outgoing
394 * messages, and to reset the serial in dbus_message_copy;
395 * this assertion should catch a double-set on outgoing.
397 _dbus_assert (_dbus_header_get_serial (header) == 0 ||
400 _dbus_marshal_set_uint32 (&header->data,
407 * See dbus_message_get_serial()
409 * @param header the header
410 * @returns the client serial
413 _dbus_header_get_serial (DBusHeader *header)
415 return _dbus_marshal_read_uint32 (&header->data,
422 * Re-initializes a header that was previously initialized and never
423 * freed. After this, to make the header valid you have to call
424 * _dbus_header_create().
426 * @param header header to re-initialize
427 * @param byte_order byte order of the header
430 _dbus_header_reinit (DBusHeader *header,
433 _dbus_string_set_length (&header->data, 0);
435 header->byte_order = byte_order;
438 _dbus_header_cache_invalidate_all (header);
442 * Initializes a header, but doesn't prepare it for use;
443 * to make the header valid, you have to call _dbus_header_create().
445 * @param header header to initialize
446 * @param byte_order byte order of the header
447 * @returns #FALSE if not enough memory
450 _dbus_header_init (DBusHeader *header,
453 if (!_dbus_string_init_preallocated (&header->data, 32))
456 _dbus_header_reinit (header, byte_order);
464 * @param header the header
467 _dbus_header_free (DBusHeader *header)
469 _dbus_string_free (&header->data);
473 * Initializes dest with a copy of the given header.
474 * Resets the message serial to 0 on the copy.
476 * @param header header to copy
477 * @param dest destination for copy
478 * @returns #FALSE if not enough memory
481 _dbus_header_copy (const DBusHeader *header,
486 if (!_dbus_string_init_preallocated (&dest->data,
487 _dbus_string_get_length (&header->data)))
490 if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
492 _dbus_string_free (&dest->data);
496 /* Reset the serial */
497 _dbus_header_set_serial (dest, 0);
503 * Fills in the primary fields of the header, so the header is ready
504 * for use. #NULL may be specified for some or all of the fields to
505 * avoid adding those fields. Some combinations of fields don't make
506 * sense, and passing them in will trigger an assertion failure.
508 * @param header the header
509 * @param message_type the message type
510 * @param destination destination field or #NULL
511 * @param path path field or #NULL
512 * @param interface interface field or #NULL
513 * @param member member field or #NULL
514 * @param error_name error name or #NULL
515 * @returns #FALSE if not enough memory
518 _dbus_header_create (DBusHeader *header,
520 const char *destination,
522 const char *interface,
524 const char *error_name)
526 unsigned char v_BYTE;
527 dbus_uint32_t v_UINT32;
528 DBusTypeWriter writer;
529 DBusTypeWriter array;
531 _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
533 !(interface || member || error_name));
534 _dbus_assert (_dbus_string_get_length (&header->data) == 0);
536 if (!reserve_header_padding (header))
539 _dbus_type_writer_init_values_only (&writer, header->byte_order,
540 &_dbus_header_signature_str, 0,
542 HEADER_END_BEFORE_PADDING (header));
544 v_BYTE = header->byte_order;
545 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
549 v_BYTE = message_type;
550 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
554 v_BYTE = 0; /* flags */
555 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
559 v_BYTE = DBUS_MAJOR_PROTOCOL_VERSION;
560 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
564 v_UINT32 = 0; /* body length */
565 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
569 v_UINT32 = 0; /* serial */
570 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
574 if (!_dbus_type_writer_recurse (&writer, DBUS_TYPE_ARRAY,
575 &_dbus_header_signature_str,
576 FIELDS_ARRAY_SIGNATURE_OFFSET,
580 /* Marshal all the fields (Marshall Fields?) */
584 if (!write_basic_field (&array,
585 DBUS_HEADER_FIELD_PATH,
586 DBUS_TYPE_OBJECT_PATH,
591 if (destination != NULL)
593 if (!write_basic_field (&array,
594 DBUS_HEADER_FIELD_DESTINATION,
600 if (interface != NULL)
602 if (!write_basic_field (&array,
603 DBUS_HEADER_FIELD_INTERFACE,
611 if (!write_basic_field (&array,
612 DBUS_HEADER_FIELD_MEMBER,
618 if (error_name != NULL)
620 if (!write_basic_field (&array,
621 DBUS_HEADER_FIELD_ERROR_NAME,
627 if (!_dbus_type_writer_unrecurse (&writer, &array))
630 correct_header_padding (header);
635 _dbus_string_delete (&header->data, 0,
636 _dbus_string_get_length (&header->data) - header->padding);
637 correct_header_padding (header);
643 * Given data long enough to contain the length of the message body
644 * and the fields array, check whether the data is long enough to
645 * contain the entire message (assuming the claimed lengths are
646 * accurate). Also checks that the lengths are in sanity parameters.
648 * @param max_message_length maximum length of a valid message
649 * @param validity return location for why the data is invalid if it is
650 * @param byte_order return location for byte order
651 * @param fields_array_len return location for claimed fields array length
652 * @param header_len return location for claimed header length
653 * @param body_len return location for claimed body length
654 * @param str the data
655 * @param start start of data, 8-aligned
656 * @param len length of data
657 * @returns #TRUE if the data is long enough for the claimed length, and the lengths were valid
660 _dbus_header_have_message_untrusted (int max_message_length,
661 DBusValidity *validity,
663 int *fields_array_len,
666 const DBusString *str,
671 dbus_uint32_t header_len_unsigned;
672 dbus_uint32_t fields_array_len_unsigned;
673 dbus_uint32_t body_len_unsigned;
675 _dbus_assert (start >= 0);
676 _dbus_assert (start < _DBUS_INT32_MAX / 2);
677 _dbus_assert (len >= 0);
679 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
681 *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
683 if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
685 *validity = DBUS_INVALID_BAD_BYTE_ORDER;
689 _dbus_assert (FIELDS_ARRAY_LENGTH_OFFSET + 4 <= len);
690 fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
693 if (fields_array_len_unsigned > (unsigned) max_message_length)
695 *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
699 _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
700 body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
703 if (body_len_unsigned > (unsigned) max_message_length)
705 *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
709 header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
710 header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
712 /* overflow should be impossible since the lengths aren't allowed to
715 _dbus_assert (max_message_length < _DBUS_INT32_MAX / 2);
716 if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
718 *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
722 _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT32_MAX);
723 _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT32_MAX);
724 _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT32_MAX);
726 *body_len = body_len_unsigned;
727 *fields_array_len = fields_array_len_unsigned;
728 *header_len = header_len_unsigned;
730 *validity = DBUS_VALID;
732 _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
733 len, body_len_unsigned, header_len_unsigned,
734 body_len_unsigned + header_len_unsigned);
736 return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
740 check_mandatory_fields (DBusHeader *header)
742 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
744 switch (_dbus_header_get_message_type (header))
746 case DBUS_MESSAGE_TYPE_SIGNAL:
747 REQUIRE_FIELD (INTERFACE);
748 /* FALL THRU - signals also require the path and member */
749 case DBUS_MESSAGE_TYPE_METHOD_CALL:
750 REQUIRE_FIELD (PATH);
751 REQUIRE_FIELD (MEMBER);
753 case DBUS_MESSAGE_TYPE_ERROR:
754 REQUIRE_FIELD (ERROR_NAME);
755 REQUIRE_FIELD (REPLY_SERIAL);
757 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
758 REQUIRE_FIELD (REPLY_SERIAL);
761 /* other message types allowed but ignored */
769 load_and_validate_field (DBusHeader *header,
771 DBusTypeReader *variant_reader)
775 const DBusString *value_str;
778 dbus_uint32_t v_UINT32;
780 dbus_bool_t (* string_validation_func) (const DBusString *str,
783 /* Supposed to have been checked already */
784 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
785 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
787 /* Before we can cache a field, we need to know it has the right type */
788 type = _dbus_type_reader_get_current_type (variant_reader);
790 _dbus_assert (_dbus_header_field_types[field].code == field);
792 expected_type = EXPECTED_TYPE_OF_FIELD (field);
793 if (type != expected_type)
795 _dbus_verbose ("Field %d should have type %d but has %d\n",
796 field, expected_type, type);
797 return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
800 /* If the field was provided twice, we aren't happy */
801 if (header->fields[field].value_pos >= 0)
803 _dbus_verbose ("Header field %d seen a second time\n", field);
804 return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
807 /* Now we can cache and look at the field content */
808 _dbus_verbose ("initially caching field %d\n", field);
809 _dbus_header_cache_one (header, field, variant_reader);
811 string_validation_func = NULL;
813 /* make compiler happy that all this is initialized */
818 bad_string_code = DBUS_VALID;
820 if (expected_type == DBUS_TYPE_UINT32)
822 _dbus_header_get_field_basic (header, field, expected_type,
825 else if (expected_type == DBUS_TYPE_STRING ||
826 expected_type == DBUS_TYPE_OBJECT_PATH ||
827 expected_type == DBUS_TYPE_SIGNATURE)
829 _dbus_header_get_field_raw (header, field,
830 &value_str, &value_pos);
831 str_data_pos = _DBUS_ALIGN_VALUE (value_pos, 4) + 4;
835 _dbus_assert_not_reached ("none of the known fields should have this type");
840 case DBUS_HEADER_FIELD_DESTINATION:
841 string_validation_func = _dbus_validate_bus_name;
842 bad_string_code = DBUS_INVALID_BAD_DESTINATION;
844 case DBUS_HEADER_FIELD_INTERFACE:
845 string_validation_func = _dbus_validate_interface;
846 bad_string_code = DBUS_INVALID_BAD_INTERFACE;
848 if (_dbus_string_equal_substring (&_dbus_local_interface_str,
850 _dbus_string_get_length (&_dbus_local_interface_str),
851 value_str, str_data_pos))
853 _dbus_verbose ("Message is on the local interface\n");
854 return DBUS_INVALID_USES_LOCAL_INTERFACE;
858 case DBUS_HEADER_FIELD_MEMBER:
859 string_validation_func = _dbus_validate_member;
860 bad_string_code = DBUS_INVALID_BAD_MEMBER;
863 case DBUS_HEADER_FIELD_ERROR_NAME:
864 string_validation_func = _dbus_validate_error_name;
865 bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
868 case DBUS_HEADER_FIELD_SENDER:
869 string_validation_func = _dbus_validate_bus_name;
870 bad_string_code = DBUS_INVALID_BAD_SENDER;
873 case DBUS_HEADER_FIELD_PATH:
874 /* OBJECT_PATH was validated generically due to its type */
875 string_validation_func = NULL;
877 if (_dbus_string_equal_substring (&_dbus_local_path_str,
879 _dbus_string_get_length (&_dbus_local_path_str),
880 value_str, str_data_pos))
882 _dbus_verbose ("Message is from the local path\n");
883 return DBUS_INVALID_USES_LOCAL_PATH;
887 case DBUS_HEADER_FIELD_REPLY_SERIAL:
891 return DBUS_INVALID_BAD_SERIAL;
895 case DBUS_HEADER_FIELD_SIGNATURE:
896 /* SIGNATURE validated generically due to its type */
897 string_validation_func = NULL;
901 _dbus_assert_not_reached ("unknown field shouldn't be seen here");
905 if (string_validation_func)
909 _dbus_assert (bad_string_code != DBUS_VALID);
911 len = _dbus_marshal_read_uint32 (value_str, value_pos,
912 header->byte_order, NULL);
915 _dbus_verbose ("Validating string header field; code %d if fails\n",
918 if (!(*string_validation_func) (value_str, str_data_pos, len))
919 return bad_string_code;
926 * Creates a message header from potentially-untrusted data. The
927 * return value is #TRUE if there was enough memory and the data was
928 * valid. If it returns #TRUE, the header will be created. If it
929 * returns #FALSE and *validity == #DBUS_VALIDITY_UNKNOWN_OOM_ERROR,
930 * then there wasn't enough memory. If it returns #FALSE
931 * and *validity != #DBUS_VALIDITY_UNKNOWN_OOM_ERROR then the data was
934 * The byte_order, fields_array_len, and body_len args should be from
935 * _dbus_header_have_message_untrusted(). Validation performed in
936 * _dbus_header_have_message_untrusted() is assumed to have been
939 * @param header the header (must be initialized)
940 * @param mode whether to do validation
941 * @param validity return location for invalidity reason
942 * @param byte_order byte order from header
943 * @param fields_array_len claimed length of fields array
944 * @param body_len claimed length of body
945 * @param header_len claimed length of header
946 * @param str a string
947 * @param start start of header, 8-aligned
948 * @param len length of string to look at
949 * @returns #FALSE if no memory or data was invalid, #TRUE otherwise
952 _dbus_header_load (DBusHeader *header,
953 DBusValidationMode mode,
954 DBusValidity *validity,
956 int fields_array_len,
959 const DBusString *str,
965 DBusTypeReader reader;
966 DBusTypeReader array_reader;
967 unsigned char v_byte;
968 dbus_uint32_t v_uint32;
969 dbus_uint32_t serial;
974 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
975 _dbus_assert (header_len <= len);
976 _dbus_assert (_dbus_string_get_length (&header->data) == 0);
978 if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
980 _dbus_verbose ("Failed to copy buffer into new header\n");
981 *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
985 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
987 leftover = len - header_len - body_len - start;
991 v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
1003 _dbus_assert (leftover < len);
1005 padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
1006 padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
1007 _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
1008 _dbus_assert (start + header_len == padding_start + padding_len);
1010 if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1012 if (!_dbus_string_validate_nul (str, padding_start, padding_len))
1014 *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1019 header->padding = padding_len;
1021 if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1023 *validity = DBUS_VALID;
1027 /* We now know the data is well-formed, but we have to check that
1031 _dbus_type_reader_init (&reader,
1033 &_dbus_header_signature_str, 0,
1037 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1038 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BYTE_ORDER_OFFSET);
1039 _dbus_type_reader_read_basic (&reader, &v_byte);
1040 _dbus_type_reader_next (&reader);
1042 _dbus_assert (v_byte == byte_order);
1045 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1046 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == TYPE_OFFSET);
1047 _dbus_type_reader_read_basic (&reader, &v_byte);
1048 _dbus_type_reader_next (&reader);
1050 /* unknown message types are supposed to be ignored, so only validation here is
1051 * that it isn't invalid
1053 if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1055 *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1060 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1061 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FLAGS_OFFSET);
1062 _dbus_type_reader_read_basic (&reader, &v_byte);
1063 _dbus_type_reader_next (&reader);
1065 /* unknown flags should be ignored */
1067 /* PROTOCOL VERSION */
1068 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1069 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == VERSION_OFFSET);
1070 _dbus_type_reader_read_basic (&reader, &v_byte);
1071 _dbus_type_reader_next (&reader);
1073 if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1075 *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1080 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
1081 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BODY_LENGTH_OFFSET);
1082 _dbus_type_reader_read_basic (&reader, &v_uint32);
1083 _dbus_type_reader_next (&reader);
1085 _dbus_assert (body_len == (signed) v_uint32);
1088 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
1089 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == SERIAL_OFFSET);
1090 _dbus_type_reader_read_basic (&reader, &serial);
1091 _dbus_type_reader_next (&reader);
1095 *validity = DBUS_INVALID_BAD_SERIAL;
1099 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_ARRAY);
1100 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FIELDS_ARRAY_LENGTH_OFFSET);
1102 _dbus_type_reader_recurse (&reader, &array_reader);
1103 while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1105 DBusTypeReader struct_reader;
1106 DBusTypeReader variant_reader;
1107 unsigned char field_code;
1109 _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT);
1111 _dbus_type_reader_recurse (&array_reader, &struct_reader);
1113 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_BYTE);
1114 _dbus_type_reader_read_basic (&struct_reader, &field_code);
1115 _dbus_type_reader_next (&struct_reader);
1117 if (field_code == DBUS_HEADER_FIELD_INVALID)
1119 _dbus_verbose ("invalid header field code\n");
1120 *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1124 if (field_code > DBUS_HEADER_FIELD_LAST)
1126 _dbus_verbose ("unknown header field code %d, skipping\n",
1131 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT);
1132 _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1134 v = load_and_validate_field (header, field_code, &variant_reader);
1135 if (v != DBUS_VALID)
1137 _dbus_verbose ("Field %d was invalid\n", field_code);
1143 _dbus_type_reader_next (&array_reader);
1146 /* Anything we didn't fill in is now known not to exist */
1148 while (i <= DBUS_HEADER_FIELD_LAST)
1150 if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1151 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1155 v = check_mandatory_fields (header);
1156 if (v != DBUS_VALID)
1158 _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1163 *validity = DBUS_VALID;
1167 _dbus_string_set_length (&header->data, 0);
1172 * Fills in the correct body length.
1174 * @param header the header
1175 * @param body_len the length of the body
1178 _dbus_header_update_lengths (DBusHeader *header,
1181 _dbus_marshal_set_uint32 (&header->data,
1184 header->byte_order);
1188 find_field_for_modification (DBusHeader *header,
1190 DBusTypeReader *reader,
1191 DBusTypeReader *realign_root)
1197 _dbus_type_reader_init (realign_root,
1199 &_dbus_header_signature_str,
1200 FIELDS_ARRAY_SIGNATURE_OFFSET,
1202 FIELDS_ARRAY_LENGTH_OFFSET);
1204 _dbus_type_reader_recurse (realign_root, reader);
1206 while (_dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID)
1209 unsigned char field_code;
1211 _dbus_type_reader_recurse (reader, &sub);
1213 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
1214 _dbus_type_reader_read_basic (&sub, &field_code);
1216 if (field_code == (unsigned) field)
1218 _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_STRUCT);
1223 _dbus_type_reader_next (reader);
1231 * Sets the value of a field with basic type. If the value is a string
1232 * value, it isn't allowed to be #NULL. If the field doesn't exist,
1233 * it will be created.
1235 * @param header the header
1236 * @param field the field to set
1237 * @param type the type of the value
1238 * @param value the value as for _dbus_marshal_set_basic()
1239 * @returns #FALSE if no memory
1242 _dbus_header_set_field_basic (DBusHeader *header,
1247 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
1249 if (!reserve_header_padding (header))
1252 /* If the field exists we set, otherwise we append */
1253 if (_dbus_header_cache_check (header, field))
1255 DBusTypeReader reader;
1256 DBusTypeReader realign_root;
1258 if (!find_field_for_modification (header, field,
1259 &reader, &realign_root))
1260 _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1262 if (!set_basic_field (&reader, field, type, value, &realign_root))
1267 DBusTypeWriter writer;
1268 DBusTypeWriter array;
1270 _dbus_type_writer_init_values_only (&writer,
1272 &_dbus_header_signature_str,
1273 FIELDS_ARRAY_SIGNATURE_OFFSET,
1275 FIELDS_ARRAY_LENGTH_OFFSET);
1277 /* recurse into array without creating a new length, and jump to
1280 if (!_dbus_type_writer_append_array (&writer,
1281 &_dbus_header_signature_str,
1282 FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET,
1284 _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1286 _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1287 _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1288 _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1290 if (!write_basic_field (&array,
1291 field, type, value))
1294 if (!_dbus_type_writer_unrecurse (&writer, &array))
1295 _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1298 correct_header_padding (header);
1300 /* We could be smarter about this (only invalidate fields after the
1301 * one we modified, or even only if the one we modified changed
1302 * length). But this hack is a start.
1304 _dbus_header_cache_invalidate_all (header);
1310 * Gets the value of a field with basic type. If the field
1311 * doesn't exist, returns #FALSE, otherwise returns #TRUE.
1313 * @param header the header
1314 * @param field the field to get
1315 * @param type the type of the value
1316 * @param value the value as for _dbus_marshal_read_basic()
1317 * @returns #FALSE if the field doesn't exist
1320 _dbus_header_get_field_basic (DBusHeader *header,
1325 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
1326 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
1327 _dbus_assert (_dbus_header_field_types[field].code == field);
1328 /* in light of this you might ask why the type is passed in;
1329 * the only rationale I can think of is so the caller has
1330 * to specify its expectation and breaks if we change it
1332 _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1334 if (!_dbus_header_cache_check (header, field))
1337 _dbus_assert (header->fields[field].value_pos >= 0);
1339 _dbus_marshal_read_basic (&header->data,
1340 header->fields[field].value_pos,
1341 type, value, header->byte_order,
1348 * Gets the raw marshaled data for a field. If the field doesn't
1349 * exist, returns #FALSE, otherwise returns #TRUE. Returns the start
1350 * of the marshaled data, i.e. usually the byte where the length
1351 * starts (for strings and arrays) or for basic types just the value
1354 * @param header the header
1355 * @param field the field to get
1356 * @param str return location for the data string
1357 * @param pos return location for start of field value
1358 * @returns #FALSE if the field doesn't exist
1361 _dbus_header_get_field_raw (DBusHeader *header,
1363 const DBusString **str,
1366 if (!_dbus_header_cache_check (header, field))
1370 *str = &header->data;
1372 *pos = header->fields[field].value_pos;
1378 * Deletes a field, if it exists.
1380 * @param header the header
1381 * @param field the field to delete
1382 * @returns #FALSE if no memory
1385 _dbus_header_delete_field (DBusHeader *header,
1388 DBusTypeReader reader;
1389 DBusTypeReader realign_root;
1391 if (_dbus_header_cache_known_nonexistent (header, field))
1392 return TRUE; /* nothing to do */
1394 /* Scan to the field we want, delete and realign, reappend
1395 * padding. Field may turn out not to exist.
1397 if (!find_field_for_modification (header, field,
1398 &reader, &realign_root))
1399 return TRUE; /* nothing to do */
1401 if (!reserve_header_padding (header))
1404 if (!_dbus_type_reader_delete (&reader,
1408 correct_header_padding (header);
1410 _dbus_header_cache_invalidate_all (header);
1412 _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1418 * Toggles a message flag bit, turning on the bit if value = TRUE and
1419 * flipping it off if value = FALSE.
1421 * @param header the header
1422 * @param flag the message flag to toggle
1423 * @param value toggle on or off
1426 _dbus_header_toggle_flag (DBusHeader *header,
1430 unsigned char *flags_p;
1432 flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1);
1441 * Gets a message flag bit, returning TRUE if the bit is set.
1443 * @param header the header
1444 * @param flag the message flag to get
1445 * @returns #TRUE if the flag is set
1448 _dbus_header_get_flag (DBusHeader *header,
1451 const unsigned char *flags_p;
1453 flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1);
1455 return (*flags_p & flag) != 0;
1459 * Swaps the header into the given order if required.
1461 * @param header the header
1462 * @param new_order the new byte order
1465 _dbus_header_byteswap (DBusHeader *header,
1468 if (header->byte_order == new_order)
1471 _dbus_marshal_byteswap (&_dbus_header_signature_str,
1472 0, header->byte_order,
1476 header->byte_order = new_order;
1481 #ifdef DBUS_BUILD_TESTS
1482 #include "dbus-test.h"
1486 _dbus_marshal_header_test (void)
1492 #endif /* DBUS_BUILD_TESTS */