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-marshal-header.h"
25 #include "dbus-marshal-recursive.h"
28 * @addtogroup DBusMarshal
34 /* Not thread locked, but strictly const/read-only so should be OK
36 _DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE);
37 _DBUS_STRING_DEFINE_STATIC(_dbus_local_interface_str, DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL);
38 _DBUS_STRING_DEFINE_STATIC(_dbus_local_path_str, DBUS_PATH_ORG_FREEDESKTOP_LOCAL);
40 #define FIELDS_ARRAY_SIGNATURE_OFFSET 6
41 #define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET 7
44 /** Offset to byte order from start of header */
45 #define BYTE_ORDER_OFFSET 0
46 /** Offset to type from start of header */
48 /** Offset to flags from start of header */
49 #define FLAGS_OFFSET 2
50 /** Offset to version from start of header */
51 #define VERSION_OFFSET 3
52 /** Offset to body length from start of header */
53 #define BODY_LENGTH_OFFSET 4
54 /** Offset to client serial from start of header */
55 #define SERIAL_OFFSET 8
56 /** Offset to fields array length from start of header */
57 #define FIELDS_ARRAY_LENGTH_OFFSET 12
58 /** Offset to first field in header */
59 #define FIRST_FIELD_OFFSET 16
67 static const HeaderFieldType
68 _dbus_header_field_types[DBUS_HEADER_FIELD_LAST+1] = {
69 { DBUS_HEADER_FIELD_INVALID, DBUS_TYPE_INVALID },
70 { DBUS_HEADER_FIELD_PATH, DBUS_TYPE_OBJECT_PATH },
71 { DBUS_HEADER_FIELD_INTERFACE, DBUS_TYPE_STRING },
72 { DBUS_HEADER_FIELD_MEMBER, DBUS_TYPE_STRING },
73 { DBUS_HEADER_FIELD_ERROR_NAME, DBUS_TYPE_STRING },
74 { DBUS_HEADER_FIELD_REPLY_SERIAL, DBUS_TYPE_UINT32 },
75 { DBUS_HEADER_FIELD_DESTINATION, DBUS_TYPE_STRING },
76 { DBUS_HEADER_FIELD_SENDER, DBUS_TYPE_STRING },
77 { DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE }
80 #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type)
82 #define MAX_POSSIBLE_HEADER_PADDING 7
84 reserve_header_padding (DBusHeader *header)
86 _dbus_assert (header->padding <= MAX_POSSIBLE_HEADER_PADDING);
88 if (!_dbus_string_lengthen (&header->data,
89 MAX_POSSIBLE_HEADER_PADDING - header->padding))
91 header->padding = MAX_POSSIBLE_HEADER_PADDING;
96 correct_header_padding (DBusHeader *header)
100 _dbus_assert (header->padding == 7);
102 _dbus_string_shorten (&header->data, header->padding);
103 unpadded_len = _dbus_string_get_length (&header->data);
105 if (!_dbus_string_align_length (&header->data, 8))
106 _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");
108 header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
111 #define HEADER_END_BEFORE_PADDING(header) \
112 (_dbus_string_get_length (&(header)->data) - (header)->padding)
115 * Invalidates all fields in the cache. This may be used when the
116 * cache is totally uninitialized (contains junk) so should not
117 * look at what's in there now.
119 * @param header the header
122 _dbus_header_cache_invalidate_all (DBusHeader *header)
127 while (i <= DBUS_HEADER_FIELD_LAST)
129 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN;
137 * @param header the header
138 * @param field_code the field
139 * @param variant_reader the reader for the variant in the field
142 _dbus_header_cache_one (DBusHeader *header,
144 DBusTypeReader *variant_reader)
148 variant_type = _dbus_type_reader_get_current_type (variant_reader);
150 header->fields[field_code].value_pos =
151 _dbus_type_reader_get_value_pos (variant_reader);
154 _dbus_verbose ("cached value_pos %d for field %d\n",
155 header->fields[field_code].value_pos, field_code)
160 * Revalidates the fields cache
162 * @param header the header
165 _dbus_header_cache_revalidate (DBusHeader *header)
167 DBusTypeReader array;
168 DBusTypeReader reader;
172 while (i <= DBUS_HEADER_FIELD_LAST)
174 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
178 _dbus_type_reader_init (&reader,
180 &_dbus_header_signature_str,
181 FIELDS_ARRAY_SIGNATURE_OFFSET,
183 FIELDS_ARRAY_LENGTH_OFFSET);
185 _dbus_type_reader_recurse (&reader, &array);
187 while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
190 DBusTypeReader variant;
191 unsigned char field_code;
193 _dbus_type_reader_recurse (&array, &sub);
195 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
196 _dbus_type_reader_read_basic (&sub, &field_code);
198 /* Unknown fields should be ignored */
199 if (field_code > DBUS_HEADER_FIELD_LAST)
202 _dbus_type_reader_next (&sub);
204 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_VARIANT);
205 _dbus_type_reader_recurse (&sub, &variant);
207 _dbus_header_cache_one (header, field_code, &variant);
210 _dbus_type_reader_next (&array);
215 * Checks for a field, updating the cache if required.
217 * @param header the header
218 * @param field the field to check
219 * @returns #FALSE if the field doesn't exist
222 _dbus_header_cache_check (DBusHeader *header,
225 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
227 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
228 _dbus_header_cache_revalidate (header);
230 if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
237 * Checks whether a field is known not to exist. It may exist
238 * even if it's not known to exist.
240 * @param header the header
241 * @param field the field to check
242 * @returns #FALSE if the field definitely doesn't exist
245 _dbus_header_cache_known_nonexistent (DBusHeader *header,
248 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
250 return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
254 * Writes a struct of { byte, variant } with the given basic type.
256 * @param writer the writer (should be ready to write a struct)
257 * @param type the type of the value
258 * @param value the value as for _dbus_marshal_set_basic()
259 * @returns #FALSE if no memory
262 write_basic_field (DBusTypeWriter *writer,
268 DBusTypeWriter variant;
271 unsigned char field_byte;
272 DBusString contained_type;
275 start = writer->value_pos;
276 padding = _dbus_string_get_length (writer->value_str) - start;
278 if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
283 if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE,
289 _dbus_string_init_const_len (&contained_type, buf, 1);
291 if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT,
292 &contained_type, 0, &variant))
295 if (!_dbus_type_writer_write_basic (&variant, type, value))
298 if (!_dbus_type_writer_unrecurse (&sub, &variant))
301 if (!_dbus_type_writer_unrecurse (writer, &sub))
307 _dbus_string_delete (writer->value_str,
309 _dbus_string_get_length (writer->value_str) - start - padding);
314 * Sets a struct of { byte, variant } with the given basic type.
316 * @param reader the reader (should be iterating over the array pointing at the field to set)
317 * @param type the type of the value
318 * @param value the value as for _dbus_marshal_set_basic()
319 * @param realign_root where to realign from
320 * @returns #FALSE if no memory
323 set_basic_field (DBusTypeReader *reader,
327 const DBusTypeReader *realign_root)
330 DBusTypeReader variant;
332 _dbus_type_reader_recurse (reader, &sub);
334 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
335 #ifndef DBUS_DISABLE_ASSERT
337 unsigned char v_BYTE;
338 _dbus_type_reader_read_basic (&sub, &v_BYTE);
339 _dbus_assert (((int) v_BYTE) == field);
343 if (!_dbus_type_reader_next (&sub))
344 _dbus_assert_not_reached ("no variant field?");
346 _dbus_type_reader_recurse (&sub, &variant);
347 _dbus_assert (_dbus_type_reader_get_current_type (&variant) == type);
349 if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
356 * Gets the type of the message.
358 * @param header the header
362 _dbus_header_get_message_type (DBusHeader *header)
366 type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
367 _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
373 * Sets the serial number of a header. This can only be done once on
376 * @param header the header
377 * @param serial the serial
380 _dbus_header_set_serial (DBusHeader *header,
381 dbus_uint32_t serial)
383 /* we use this function to set the serial on outgoing
384 * messages, and to reset the serial in dbus_message_copy;
385 * this assertion should catch a double-set on outgoing.
387 _dbus_assert (_dbus_header_get_serial (header) == 0 ||
390 _dbus_marshal_set_uint32 (&header->data,
397 * See dbus_message_get_serial()
399 * @param header the header
400 * @returns the client serial
403 _dbus_header_get_serial (DBusHeader *header)
405 return _dbus_marshal_read_uint32 (&header->data,
412 * Re-initializes a header that was previously initialized and never
413 * freed. After this, to make the header valid you have to call
414 * _dbus_header_create().
416 * @param header header to re-initialize
417 * @param byte_order byte order of the header
420 _dbus_header_reinit (DBusHeader *header,
423 _dbus_string_set_length (&header->data, 0);
425 header->byte_order = byte_order;
428 _dbus_header_cache_invalidate_all (header);
432 * Initializes a header, but doesn't prepare it for use;
433 * to make the header valid, you have to call _dbus_header_create().
435 * @param header header to initialize
436 * @param byte_order byte order of the header
437 * @returns #FALSE if not enough memory
440 _dbus_header_init (DBusHeader *header,
443 if (!_dbus_string_init_preallocated (&header->data, 32))
446 _dbus_header_reinit (header, byte_order);
454 * @param header the header
457 _dbus_header_free (DBusHeader *header)
459 _dbus_string_free (&header->data);
463 * Initializes dest with a copy of the given header.
464 * Resets the message serial to 0 on the copy.
466 * @param header header to copy
467 * @param dest destination for copy
468 * @returns #FALSE if not enough memory
471 _dbus_header_copy (const DBusHeader *header,
476 if (!_dbus_string_init_preallocated (&dest->data,
477 _dbus_string_get_length (&header->data)))
480 if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
482 _dbus_string_free (&dest->data);
486 /* Reset the serial */
487 _dbus_header_set_serial (dest, 0);
493 * Fills in the primary fields of the header, so the header is ready
494 * for use. #NULL may be specified for some or all of the fields to
495 * avoid adding those fields. Some combinations of fields don't make
496 * sense, and passing them in will trigger an assertion failure.
498 * @param header the header
499 * @param message_type the message type
500 * @param destination service field or #NULL
501 * @param path path field or #NULL
502 * @param interface interface field or #NULL
503 * @param member member field or #NULL
504 * @param error_name error name or #NULL
505 * @returns #FALSE if not enough memory
508 _dbus_header_create (DBusHeader *header,
510 const char *destination,
512 const char *interface,
514 const char *error_name)
516 unsigned char v_BYTE;
517 dbus_uint32_t v_UINT32;
518 DBusTypeWriter writer;
519 DBusTypeWriter array;
521 _dbus_assert ((interface && member) ||
523 !(interface || member || error_name));
524 _dbus_assert (_dbus_string_get_length (&header->data) == 0);
526 if (!reserve_header_padding (header))
529 _dbus_type_writer_init_values_only (&writer, header->byte_order,
530 &_dbus_header_signature_str, 0,
532 HEADER_END_BEFORE_PADDING (header));
534 v_BYTE = header->byte_order;
535 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
539 v_BYTE = message_type;
540 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
544 v_BYTE = 0; /* flags */
545 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
549 v_BYTE = DBUS_MAJOR_PROTOCOL_VERSION;
550 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
554 v_UINT32 = 0; /* body length */
555 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
559 v_UINT32 = 0; /* serial */
560 if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
564 if (!_dbus_type_writer_recurse (&writer, DBUS_TYPE_ARRAY,
565 &_dbus_header_signature_str,
566 FIELDS_ARRAY_SIGNATURE_OFFSET,
570 /* Marshal all the fields (Marshall Fields?) */
574 if (!write_basic_field (&array,
575 DBUS_HEADER_FIELD_PATH,
576 DBUS_TYPE_OBJECT_PATH,
581 if (destination != NULL)
583 if (!write_basic_field (&array,
584 DBUS_HEADER_FIELD_DESTINATION,
590 if (interface != NULL)
592 if (!write_basic_field (&array,
593 DBUS_HEADER_FIELD_INTERFACE,
601 if (!write_basic_field (&array,
602 DBUS_HEADER_FIELD_MEMBER,
608 if (error_name != NULL)
610 if (!write_basic_field (&array,
611 DBUS_HEADER_FIELD_ERROR_NAME,
617 if (!_dbus_type_writer_unrecurse (&writer, &array))
620 correct_header_padding (header);
625 _dbus_string_delete (&header->data, 0,
626 _dbus_string_get_length (&header->data) - header->padding);
627 correct_header_padding (header);
633 * Given data long enough to contain the length of the message body
634 * and the fields array, check whether the data is long enough to
635 * contain the entire message (assuming the claimed lengths are
636 * accurate). Also checks that the lengths are in sanity parameters.
638 * @param validity return location for why the data is invalid if it is
639 * @param byte_order return location for byte order
640 * @param fields_array_len return location for claimed fields array length
641 * @param header_len return location for claimed header length
642 * @param body_len return location for claimed body length
643 * @param str the data
644 * @param start start of data, 8-aligned
645 * @param len length of data
646 * @returns #TRUE if the data is long enough for the claimed length, and the lengths were valid
649 _dbus_header_have_message_untrusted (int max_message_length,
650 DBusValidity *validity,
652 int *fields_array_len,
655 const DBusString *str,
660 dbus_uint32_t header_len_unsigned;
661 dbus_uint32_t fields_array_len_unsigned;
662 dbus_uint32_t body_len_unsigned;
664 _dbus_assert (start >= 0);
665 _dbus_assert (start < _DBUS_INT_MAX / 2);
666 _dbus_assert (len >= 0);
668 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
670 *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
672 if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
674 *validity = DBUS_INVALID_BAD_BYTE_ORDER;
678 _dbus_assert (FIELDS_ARRAY_LENGTH_OFFSET + 4 <= len);
679 fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
682 if (fields_array_len_unsigned > (unsigned) max_message_length)
684 *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
688 _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
689 body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
692 if (body_len_unsigned > (unsigned) max_message_length)
694 *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
698 header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
699 header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
701 /* overflow should be impossible since the lengths aren't allowed to
704 _dbus_assert (max_message_length < _DBUS_INT_MAX / 2);
705 if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
707 *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
711 _dbus_assert (body_len_unsigned < (unsigned) _DBUS_INT_MAX);
712 _dbus_assert (fields_array_len_unsigned < (unsigned) _DBUS_INT_MAX);
713 _dbus_assert (header_len_unsigned < (unsigned) _DBUS_INT_MAX);
715 *body_len = body_len_unsigned;
716 *fields_array_len = fields_array_len_unsigned;
717 *header_len = header_len_unsigned;
719 *validity = DBUS_VALID;
721 _dbus_verbose ("have %d bytes, need body %u + header %u = %u\n",
722 len, body_len_unsigned, header_len_unsigned,
723 body_len_unsigned + header_len_unsigned);
725 return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
729 check_mandatory_fields (DBusHeader *header)
731 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
733 switch (_dbus_header_get_message_type (header))
735 case DBUS_MESSAGE_TYPE_SIGNAL:
736 REQUIRE_FIELD (INTERFACE);
737 /* FALL THRU - signals also require the path and member */
738 case DBUS_MESSAGE_TYPE_METHOD_CALL:
739 REQUIRE_FIELD (PATH);
740 REQUIRE_FIELD (MEMBER);
742 case DBUS_MESSAGE_TYPE_ERROR:
743 REQUIRE_FIELD (ERROR_NAME);
744 REQUIRE_FIELD (REPLY_SERIAL);
746 case DBUS_MESSAGE_TYPE_METHOD_RETURN:
747 REQUIRE_FIELD (REPLY_SERIAL);
750 /* other message types allowed but ignored */
758 load_and_validate_field (DBusHeader *header,
760 DBusTypeReader *variant_reader)
764 const DBusString *value_str;
766 dbus_uint32_t v_UINT32;
768 dbus_bool_t (* string_validation_func) (const DBusString *str,
771 /* Supposed to have been checked already */
772 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
773 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
775 /* Before we can cache a field, we need to know it has the right type */
776 type = _dbus_type_reader_get_current_type (variant_reader);
778 _dbus_assert (_dbus_header_field_types[field].code == field);
780 expected_type = EXPECTED_TYPE_OF_FIELD (field);
781 if (type != expected_type)
783 _dbus_verbose ("Field %d should have type %d but has %d\n",
784 field, expected_type, type);
785 return DBUS_INVALID_HEADER_FIELD_HAS_WRONG_TYPE;
788 /* If the field was provided twice, we aren't happy */
789 if (header->fields[field].value_pos >= 0)
791 _dbus_verbose ("Header field %d seen a second time\n", field);
792 return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
795 /* Now we can cache and look at the field content */
796 _dbus_verbose ("initially caching field %d\n", field);
797 _dbus_header_cache_one (header, field, variant_reader);
799 string_validation_func = NULL;
801 /* make compiler happy that all this is initialized */
805 bad_string_code = DBUS_VALID;
807 if (expected_type == DBUS_TYPE_UINT32)
809 _dbus_header_get_field_basic (header, field, expected_type,
812 else if (expected_type == DBUS_TYPE_STRING ||
813 expected_type == DBUS_TYPE_OBJECT_PATH ||
814 expected_type == DBUS_TYPE_SIGNATURE)
816 _dbus_header_get_field_raw (header, field,
817 &value_str, &value_pos);
821 _dbus_assert_not_reached ("none of the known fields should have this type");
826 case DBUS_HEADER_FIELD_DESTINATION:
827 string_validation_func = _dbus_validate_service;
828 bad_string_code = DBUS_INVALID_BAD_DESTINATION;
830 case DBUS_HEADER_FIELD_INTERFACE:
831 string_validation_func = _dbus_validate_interface;
832 bad_string_code = DBUS_INVALID_BAD_INTERFACE;
834 if (_dbus_string_equal_substring (&_dbus_local_interface_str,
836 _dbus_string_get_length (&_dbus_local_interface_str),
837 value_str, value_pos))
839 _dbus_verbose ("Message is on the local interface\n");
840 return DBUS_INVALID_USES_LOCAL_INTERFACE;
844 case DBUS_HEADER_FIELD_MEMBER:
845 string_validation_func = _dbus_validate_member;
846 bad_string_code = DBUS_INVALID_BAD_MEMBER;
849 case DBUS_HEADER_FIELD_ERROR_NAME:
850 string_validation_func = _dbus_validate_error_name;
851 bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
854 case DBUS_HEADER_FIELD_SENDER:
855 string_validation_func = _dbus_validate_service;
856 bad_string_code = DBUS_INVALID_BAD_SENDER;
859 case DBUS_HEADER_FIELD_PATH:
860 /* OBJECT_PATH was validated generically due to its type */
861 string_validation_func = NULL;
863 _dbus_verbose ("value_str %p value_pos %d value_str_len %d\n",
864 value_str, value_pos,
865 _dbus_string_get_length (value_str));
866 if (_dbus_string_equal_substring (&_dbus_local_path_str,
868 _dbus_string_get_length (&_dbus_local_path_str),
869 value_str, value_pos))
871 _dbus_verbose ("Message is from the local path\n");
872 return DBUS_INVALID_USES_LOCAL_PATH;
876 case DBUS_HEADER_FIELD_REPLY_SERIAL:
880 return DBUS_INVALID_BAD_SERIAL;
884 case DBUS_HEADER_FIELD_SIGNATURE:
885 /* SIGNATURE validated generically due to its type */
886 string_validation_func = NULL;
890 _dbus_assert_not_reached ("unknown field shouldn't be seen here");
894 if (string_validation_func)
898 _dbus_assert (bad_string_code != DBUS_VALID);
900 len = _dbus_marshal_read_uint32 (value_str, value_pos,
901 header->byte_order, NULL);
903 if (!(*string_validation_func) (value_str, value_pos + 4, len))
904 return bad_string_code;
911 * Creates a message header from untrusted data. The return value
912 * is #TRUE if there was enough memory and the data was valid. If it
913 * returns #TRUE, the header will be created. If it returns #FALSE
914 * and *validity == #DBUS_VALID, then there wasn't enough memory. If
915 * it returns #FALSE and *validity != #DBUS_VALID then the data was
918 * The byte_order, fields_array_len, and body_len args should be from
919 * _dbus_header_have_message_untrusted(). Validation performed in
920 * _dbus_header_have_message_untrusted() is assumed to have been
923 * @param header the header (must be initialized)
924 * @param validity return location for invalidity reason
925 * @param byte_order byte order from header
926 * @param fields_array_len claimed length of fields array
927 * @param body_len claimed length of body
928 * @param header_len claimed length of header
929 * @param str a string
930 * @param start start of header, 8-aligned
931 * @param len length of string to look at
932 * @returns #FALSE if no memory or data was invalid, #TRUE otherwise
935 _dbus_header_load_untrusted (DBusHeader *header,
936 DBusValidity *validity,
938 int fields_array_len,
941 const DBusString *str,
947 DBusTypeReader reader;
948 DBusTypeReader array_reader;
949 unsigned char v_byte;
950 dbus_uint32_t v_uint32;
951 dbus_uint32_t serial;
956 _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
957 _dbus_assert (header_len <= len);
958 _dbus_assert (_dbus_string_get_length (&header->data) == 0);
960 if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
962 _dbus_verbose ("Failed to copy buffer into new header\n");
963 *validity = DBUS_VALID;
967 v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
978 _dbus_assert (leftover < len);
980 padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
981 padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
982 _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
983 _dbus_assert (start + header_len == padding_start + padding_len);
985 if (!_dbus_string_validate_nul (str, padding_start, padding_len))
987 *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
991 header->padding = padding_len;
993 /* We now know the data is well-formed, but we have to check that
997 _dbus_type_reader_init (&reader,
999 &_dbus_header_signature_str, 0,
1003 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1004 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BYTE_ORDER_OFFSET);
1005 _dbus_type_reader_read_basic (&reader, &v_byte);
1006 _dbus_type_reader_next (&reader);
1008 _dbus_assert (v_byte == byte_order);
1011 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1012 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == TYPE_OFFSET);
1013 _dbus_type_reader_read_basic (&reader, &v_byte);
1014 _dbus_type_reader_next (&reader);
1016 /* unknown message types are supposed to be ignored, so only validation here is
1017 * that it isn't invalid
1019 if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1021 *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1026 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1027 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FLAGS_OFFSET);
1028 _dbus_type_reader_read_basic (&reader, &v_byte);
1029 _dbus_type_reader_next (&reader);
1031 /* unknown flags should be ignored */
1033 /* PROTOCOL VERSION */
1034 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1035 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == VERSION_OFFSET);
1036 _dbus_type_reader_read_basic (&reader, &v_byte);
1037 _dbus_type_reader_next (&reader);
1039 if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1041 *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1046 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
1047 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BODY_LENGTH_OFFSET);
1048 _dbus_type_reader_read_basic (&reader, &v_uint32);
1049 _dbus_type_reader_next (&reader);
1051 _dbus_assert (body_len == (signed) v_uint32);
1054 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
1055 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == SERIAL_OFFSET);
1056 _dbus_type_reader_read_basic (&reader, &serial);
1057 _dbus_type_reader_next (&reader);
1061 *validity = DBUS_INVALID_BAD_SERIAL;
1065 _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_ARRAY);
1066 _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FIELDS_ARRAY_LENGTH_OFFSET);
1068 _dbus_type_reader_recurse (&reader, &array_reader);
1069 while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1071 DBusTypeReader struct_reader;
1072 DBusTypeReader variant_reader;
1073 unsigned char field_code;
1075 _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT);
1077 _dbus_type_reader_recurse (&array_reader, &struct_reader);
1079 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_BYTE);
1080 _dbus_type_reader_read_basic (&struct_reader, &field_code);
1081 _dbus_type_reader_next (&struct_reader);
1083 if (field_code == DBUS_HEADER_FIELD_INVALID)
1085 _dbus_verbose ("invalid header field code\n");
1086 *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1090 if (field_code > DBUS_HEADER_FIELD_LAST)
1092 _dbus_verbose ("unknown header field code %d, skipping\n",
1097 _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT);
1098 _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1100 v = load_and_validate_field (header, field_code, &variant_reader);
1101 if (v != DBUS_VALID)
1103 _dbus_verbose ("Field %d was invalid\n", field_code);
1109 _dbus_type_reader_next (&array_reader);
1112 /* Anything we didn't fill in is now known not to exist */
1114 while (i <= DBUS_HEADER_FIELD_LAST)
1116 if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1117 header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1121 v = check_mandatory_fields (header);
1122 if (v != DBUS_VALID)
1124 _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1129 *validity = DBUS_VALID;
1133 _dbus_string_set_length (&header->data, 0);
1138 * Fills in the correct body length.
1140 * @param header the header
1141 * @param body_len the length of the body
1144 _dbus_header_update_lengths (DBusHeader *header,
1147 _dbus_marshal_set_uint32 (&header->data,
1150 header->byte_order);
1154 find_field_for_modification (DBusHeader *header,
1156 DBusTypeReader *reader,
1157 DBusTypeReader *realign_root)
1163 _dbus_type_reader_init (realign_root,
1165 &_dbus_header_signature_str,
1166 FIELDS_ARRAY_SIGNATURE_OFFSET,
1168 FIELDS_ARRAY_LENGTH_OFFSET);
1170 _dbus_type_reader_recurse (realign_root, reader);
1172 while (_dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID)
1175 unsigned char field_code;
1177 _dbus_type_reader_recurse (reader, &sub);
1179 _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
1180 _dbus_type_reader_read_basic (&sub, &field_code);
1182 if (field_code == (unsigned) field)
1184 _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_STRUCT);
1189 _dbus_type_reader_next (reader);
1197 * Sets the value of a field with basic type. If the value is a string
1198 * value, it isn't allowed to be #NULL. If the field doesn't exist,
1199 * it will be created.
1201 * @param header the header
1202 * @param field the field to set
1203 * @param type the type of the value
1204 * @param value the value as for _dbus_marshal_set_basic()
1205 * @returns #FALSE if no memory
1208 _dbus_header_set_field_basic (DBusHeader *header,
1213 _dbus_return_val_if_fail (field <= DBUS_HEADER_FIELD_LAST, FALSE);
1215 if (!reserve_header_padding (header))
1218 /* If the field exists we set, otherwise we append */
1219 if (_dbus_header_cache_check (header, field))
1221 DBusTypeReader reader;
1222 DBusTypeReader realign_root;
1224 if (!find_field_for_modification (header, field,
1225 &reader, &realign_root))
1226 _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1228 if (!set_basic_field (&reader, field, type, value, &realign_root))
1233 DBusTypeWriter writer;
1234 DBusTypeWriter array;
1236 _dbus_type_writer_init_values_only (&writer,
1238 &_dbus_header_signature_str,
1239 FIELDS_ARRAY_SIGNATURE_OFFSET,
1241 FIELDS_ARRAY_LENGTH_OFFSET);
1243 /* recurse into array without creating a new length, and jump to
1246 if (!_dbus_type_writer_append_array (&writer,
1247 &_dbus_header_signature_str,
1248 FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET,
1250 _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1252 _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1253 _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1254 _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1256 if (!write_basic_field (&array,
1257 field, type, value))
1260 if (!_dbus_type_writer_unrecurse (&writer, &array))
1261 _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1264 correct_header_padding (header);
1266 /* We could be smarter about this (only invalidate fields after the
1267 * one we modified, or even only if the one we modified changed
1268 * length). But this hack is a start.
1270 _dbus_header_cache_invalidate_all (header);
1276 * Gets the value of a field with basic type. If the field
1277 * doesn't exist, returns #FALSE, otherwise returns #TRUE.
1279 * @param header the header
1280 * @param field the field to get
1281 * @param type the type of the value
1282 * @param value the value as for _dbus_marshal_read_basic()
1283 * @returns #FALSE if the field doesn't exist
1286 _dbus_header_get_field_basic (DBusHeader *header,
1291 _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
1292 _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
1293 _dbus_assert (_dbus_header_field_types[field].code == field);
1294 /* in light of this you might ask why the type is passed in;
1295 * the only rationale I can think of is so the caller has
1296 * to specify its expectation and breaks if we change it
1298 _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1300 if (!_dbus_header_cache_check (header, field))
1303 _dbus_assert (header->fields[field].value_pos >= 0);
1305 _dbus_marshal_read_basic (&header->data,
1306 header->fields[field].value_pos,
1307 type, value, header->byte_order,
1314 * Gets the raw marshaled data for a field. If the field doesn't
1315 * exist, returns #FALSE, otherwise returns #TRUE. Returns the start
1316 * of the marshaled data, i.e. usually the byte where the length
1317 * starts (for strings and arrays) or for basic types just the value
1320 * @param header the header
1321 * @param field the field to get
1322 * @param str return location for the data string
1323 * @param pos return location for start of field value
1324 * @returns #FALSE if the field doesn't exist
1327 _dbus_header_get_field_raw (DBusHeader *header,
1329 const DBusString **str,
1332 if (!_dbus_header_cache_check (header, field))
1336 *str = &header->data;
1338 *pos = header->fields[field].value_pos;
1344 * Deletes a field, if it exists.
1346 * @param header the header
1347 * @param field the field to delete
1348 * @returns #FALSE if no memory
1351 _dbus_header_delete_field (DBusHeader *header,
1354 DBusTypeReader reader;
1355 DBusTypeReader realign_root;
1357 if (_dbus_header_cache_known_nonexistent (header, field))
1358 return TRUE; /* nothing to do */
1360 /* Scan to the field we want, delete and realign, reappend
1361 * padding. Field may turn out not to exist.
1363 if (!find_field_for_modification (header, field,
1364 &reader, &realign_root))
1365 return TRUE; /* nothing to do */
1367 if (!reserve_header_padding (header))
1370 if (!_dbus_type_reader_delete (&reader,
1374 correct_header_padding (header);
1376 _dbus_header_cache_invalidate_all (header);
1378 _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1384 * Toggles a message flag bit, turning on the bit if value = TRUE and
1385 * flipping it off if value = FALSE.
1387 * @param header the header
1388 * @param flag the message flag to toggle
1389 * @param value toggle on or off
1392 _dbus_header_toggle_flag (DBusHeader *header,
1396 unsigned char *flags_p;
1398 flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1);
1407 * Gets a message flag bit, returning TRUE if the bit is set.
1409 * @param header the header
1410 * @param flag the message flag to get
1411 * @returns #TRUE if the flag is set
1414 _dbus_header_get_flag (DBusHeader *header,
1417 const unsigned char *flags_p;
1419 flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1);
1421 return (*flags_p & flag) != 0;
1426 #ifdef DBUS_BUILD_TESTS
1427 #include "dbus-test.h"
1431 _dbus_marshal_header_test (void)
1437 #endif /* DBUS_BUILD_TESTS */