2005-01-15 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-marshal-header.c
1 /* -*- mode: C; c-file-style: "gnu" -*- */
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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  *
22  */
23
24 #include "dbus-marshal-header.h"
25 #include "dbus-marshal-recursive.h"
26
27 /**
28  * @addtogroup DBusMarshal
29  *
30  * @{
31  */
32
33
34 /* Not thread locked, but strictly const/read-only so should be OK
35  */
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);
39
40 #define FIELDS_ARRAY_SIGNATURE_OFFSET 6
41 #define FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET 7
42
43
44 /** Offset to byte order from start of header */
45 #define BYTE_ORDER_OFFSET    0
46 /** Offset to type from start of header */
47 #define TYPE_OFFSET          1
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
60
61 typedef struct
62 {
63   unsigned char code;
64   unsigned char type;
65 } HeaderFieldType;
66
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 }
78 };
79
80 #define EXPECTED_TYPE_OF_FIELD(field) (_dbus_header_field_types[field].type)
81
82 #define MAX_POSSIBLE_HEADER_PADDING 7
83 static dbus_bool_t
84 reserve_header_padding (DBusHeader *header)
85 {
86   _dbus_assert (header->padding <= MAX_POSSIBLE_HEADER_PADDING);
87
88   if (!_dbus_string_lengthen (&header->data,
89                               MAX_POSSIBLE_HEADER_PADDING - header->padding))
90     return FALSE;
91   header->padding = MAX_POSSIBLE_HEADER_PADDING;
92   return TRUE;
93 }
94
95 static void
96 correct_header_padding (DBusHeader *header)
97 {
98   int unpadded_len;
99
100   _dbus_assert (header->padding == 7);
101
102   _dbus_string_shorten (&header->data, header->padding);
103   unpadded_len = _dbus_string_get_length (&header->data);
104
105   if (!_dbus_string_align_length (&header->data, 8))
106     _dbus_assert_not_reached ("couldn't pad header though enough padding was preallocated");
107
108   header->padding = _dbus_string_get_length (&header->data) - unpadded_len;
109 }
110
111 #define HEADER_END_BEFORE_PADDING(header) \
112   (_dbus_string_get_length (&(header)->data) - (header)->padding)
113
114 /**
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.
118  *
119  * @param header the header
120  */
121 static void
122 _dbus_header_cache_invalidate_all (DBusHeader *header)
123 {
124   int i;
125
126   i = 0;
127   while (i <= DBUS_HEADER_FIELD_LAST)
128     {
129       header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_UNKNOWN;
130       ++i;
131     }
132 }
133
134 /**
135  * Caches one field
136  *
137  * @param header the header
138  * @param field_code the field
139  * @param variant_reader the reader for the variant in the field
140  */
141 static void
142 _dbus_header_cache_one (DBusHeader     *header,
143                         int             field_code,
144                         DBusTypeReader *variant_reader)
145 {
146   int variant_type;
147
148   variant_type = _dbus_type_reader_get_current_type (variant_reader);
149
150   header->fields[field_code].value_pos =
151     _dbus_type_reader_get_value_pos (variant_reader);
152
153 #if 0
154   _dbus_verbose ("cached value_pos %d for field %d\n",
155                  header->fields[field_code].value_pos, field_code)
156 #endif
157 }
158
159 /**
160  * Revalidates the fields cache
161  *
162  * @param header the header
163  */
164 static void
165 _dbus_header_cache_revalidate (DBusHeader *header)
166 {
167   DBusTypeReader array;
168   DBusTypeReader reader;
169   int i;
170
171   i = 0;
172   while (i <= DBUS_HEADER_FIELD_LAST)
173     {
174       header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
175       ++i;
176     }
177
178   _dbus_type_reader_init (&reader,
179                           header->byte_order,
180                           &_dbus_header_signature_str,
181                           FIELDS_ARRAY_SIGNATURE_OFFSET,
182                           &header->data,
183                           FIELDS_ARRAY_LENGTH_OFFSET);
184
185   _dbus_type_reader_recurse (&reader, &array);
186
187   while (_dbus_type_reader_get_current_type (&array) != DBUS_TYPE_INVALID)
188     {
189       DBusTypeReader sub;
190       DBusTypeReader variant;
191       unsigned char field_code;
192
193       _dbus_type_reader_recurse (&array, &sub);
194
195       _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
196       _dbus_type_reader_read_basic (&sub, &field_code);
197
198       /* Unknown fields should be ignored */
199       if (field_code > DBUS_HEADER_FIELD_LAST)
200         goto next_field;
201
202       _dbus_type_reader_next (&sub);
203
204       _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_VARIANT);
205       _dbus_type_reader_recurse (&sub, &variant);
206
207       _dbus_header_cache_one (header, field_code, &variant);
208
209     next_field:
210       _dbus_type_reader_next (&array);
211     }
212 }
213
214 /**
215  * Checks for a field, updating the cache if required.
216  *
217  * @param header the header
218  * @param field the field to check
219  * @returns #FALSE if the field doesn't exist
220  */
221 static dbus_bool_t
222 _dbus_header_cache_check (DBusHeader    *header,
223                           int            field)
224 {
225   _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
226
227   if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
228     _dbus_header_cache_revalidate (header);
229
230   if (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT)
231     return FALSE;
232
233   return TRUE;
234 }
235
236 /**
237  * Checks whether a field is known not to exist. It may exist
238  * even if it's not known to exist.
239  *
240  * @param header the header
241  * @param field the field to check
242  * @returns #FALSE if the field definitely doesn't exist
243  */
244 static dbus_bool_t
245 _dbus_header_cache_known_nonexistent (DBusHeader    *header,
246                                       int            field)
247 {
248   _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
249
250   return (header->fields[field].value_pos == _DBUS_HEADER_FIELD_VALUE_NONEXISTENT);
251 }
252
253 /**
254  * Writes a struct of { byte, variant } with the given basic type.
255  *
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
260  */
261 static dbus_bool_t
262 write_basic_field (DBusTypeWriter *writer,
263                    int             field,
264                    int             type,
265                    const void     *value)
266 {
267   DBusTypeWriter sub;
268   DBusTypeWriter variant;
269   int start;
270   int padding;
271   unsigned char field_byte;
272   DBusString contained_type;
273   char buf[2];
274
275   start = writer->value_pos;
276   padding = _dbus_string_get_length (writer->value_str) - start;
277
278   if (!_dbus_type_writer_recurse (writer, DBUS_TYPE_STRUCT,
279                                   NULL, 0, &sub))
280     goto append_failed;
281
282   field_byte = field;
283   if (!_dbus_type_writer_write_basic (&sub, DBUS_TYPE_BYTE,
284                                       &field_byte))
285     goto append_failed;
286
287   buf[0] = type;
288   buf[1] = '\0';
289   _dbus_string_init_const_len (&contained_type, buf, 1);
290
291   if (!_dbus_type_writer_recurse (&sub, DBUS_TYPE_VARIANT,
292                                   &contained_type, 0, &variant))
293     goto append_failed;
294
295   if (!_dbus_type_writer_write_basic (&variant, type, value))
296     goto append_failed;
297
298   if (!_dbus_type_writer_unrecurse (&sub, &variant))
299     goto append_failed;
300
301   if (!_dbus_type_writer_unrecurse (writer, &sub))
302     goto append_failed;
303
304   return TRUE;
305
306  append_failed:
307   _dbus_string_delete (writer->value_str,
308                        start,
309                        _dbus_string_get_length (writer->value_str) - start - padding);
310   return FALSE;
311 }
312
313 /**
314  * Sets a struct of { byte, variant } with the given basic type.
315  *
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
321  */
322 static dbus_bool_t
323 set_basic_field (DBusTypeReader       *reader,
324                  int                   field,
325                  int                   type,
326                  const void           *value,
327                  const DBusTypeReader *realign_root)
328 {
329   DBusTypeReader sub;
330   DBusTypeReader variant;
331
332   _dbus_type_reader_recurse (reader, &sub);
333
334   _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
335 #ifndef DBUS_DISABLE_ASSERT
336  {
337    unsigned char v_BYTE;
338    _dbus_type_reader_read_basic (&sub, &v_BYTE);
339    _dbus_assert (((int) v_BYTE) == field);
340  }
341 #endif
342
343   if (!_dbus_type_reader_next (&sub))
344     _dbus_assert_not_reached ("no variant field?");
345
346   _dbus_type_reader_recurse (&sub, &variant);
347   _dbus_assert (_dbus_type_reader_get_current_type (&variant) == type);
348
349   if (!_dbus_type_reader_set_basic (&variant, value, realign_root))
350     return FALSE;
351
352   return TRUE;
353 }
354
355 /**
356  * Gets the type of the message.
357  *
358  * @param header the header
359  * @returns the type
360  */
361 int
362 _dbus_header_get_message_type (DBusHeader *header)
363 {
364   int type;
365
366   type = _dbus_string_get_byte (&header->data, TYPE_OFFSET);
367   _dbus_assert (type != DBUS_MESSAGE_TYPE_INVALID);
368
369   return type;
370 }
371
372 /**
373  * Sets the serial number of a header.  This can only be done once on
374  * a header.
375  *
376  * @param header the header
377  * @param serial the serial
378  */
379 void
380 _dbus_header_set_serial (DBusHeader    *header,
381                          dbus_uint32_t  serial)
382 {
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.
386    */
387   _dbus_assert (_dbus_header_get_serial (header) == 0 ||
388                 serial == 0);
389
390   _dbus_marshal_set_uint32 (&header->data,
391                             SERIAL_OFFSET,
392                             serial,
393                             header->byte_order);
394 }
395
396 /**
397  * See dbus_message_get_serial()
398  *
399  * @param header the header
400  * @returns the client serial
401  */
402 dbus_uint32_t
403 _dbus_header_get_serial (DBusHeader *header)
404 {
405   return _dbus_marshal_read_uint32 (&header->data,
406                                     SERIAL_OFFSET,
407                                     header->byte_order,
408                                     NULL);
409 }
410
411 /**
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().
415  *
416  * @param header header to re-initialize
417  * @param byte_order byte order of the header
418  */
419 void
420 _dbus_header_reinit (DBusHeader *header,
421                      int         byte_order)
422 {
423   _dbus_string_set_length (&header->data, 0);
424
425   header->byte_order = byte_order;
426   header->padding = 0;
427
428   _dbus_header_cache_invalidate_all (header);
429 }
430
431 /**
432  * Initializes a header, but doesn't prepare it for use;
433  * to make the header valid, you have to call _dbus_header_create().
434  *
435  * @param header header to initialize
436  * @param byte_order byte order of the header
437  * @returns #FALSE if not enough memory
438  */
439 dbus_bool_t
440 _dbus_header_init (DBusHeader *header,
441                    int         byte_order)
442 {
443   if (!_dbus_string_init_preallocated (&header->data, 32))
444     return FALSE;
445
446   _dbus_header_reinit (header, byte_order);
447
448   return TRUE;
449 }
450
451 /**
452  * Frees a header.
453  *
454  * @param header the header
455  */
456 void
457 _dbus_header_free (DBusHeader *header)
458 {
459   _dbus_string_free (&header->data);
460 }
461
462 /**
463  * Initializes dest with a copy of the given header.
464  * Resets the message serial to 0 on the copy.
465  *
466  * @param header header to copy
467  * @param dest destination for copy
468  * @returns #FALSE if not enough memory
469  */
470 dbus_bool_t
471 _dbus_header_copy (const DBusHeader *header,
472                    DBusHeader       *dest)
473 {
474   *dest = *header;
475
476   if (!_dbus_string_init_preallocated (&dest->data,
477                                        _dbus_string_get_length (&header->data)))
478     return FALSE;
479
480   if (!_dbus_string_copy (&header->data, 0, &dest->data, 0))
481     {
482       _dbus_string_free (&dest->data);
483       return FALSE;
484     }
485
486   /* Reset the serial */
487   _dbus_header_set_serial (dest, 0);
488
489   return TRUE;
490 }
491
492 /**
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.
497  *
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
506  */
507 dbus_bool_t
508 _dbus_header_create (DBusHeader  *header,
509                      int          message_type,
510                      const char  *destination,
511                      const char  *path,
512                      const char  *interface,
513                      const char  *member,
514                      const char  *error_name)
515 {
516   unsigned char v_BYTE;
517   dbus_uint32_t v_UINT32;
518   DBusTypeWriter writer;
519   DBusTypeWriter array;
520
521   _dbus_assert ((interface && member) ||
522                 (error_name) ||
523                 !(interface || member || error_name));
524   _dbus_assert (_dbus_string_get_length (&header->data) == 0);
525
526   if (!reserve_header_padding (header))
527     return FALSE;
528
529   _dbus_type_writer_init_values_only (&writer, header->byte_order,
530                                       &_dbus_header_signature_str, 0,
531                                       &header->data,
532                                       HEADER_END_BEFORE_PADDING (header));
533
534   v_BYTE = header->byte_order;
535   if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
536                                       &v_BYTE))
537     goto oom;
538
539   v_BYTE = message_type;
540   if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
541                                       &v_BYTE))
542     goto oom;
543
544   v_BYTE = 0; /* flags */
545   if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
546                                       &v_BYTE))
547     goto oom;
548
549   v_BYTE = DBUS_MAJOR_PROTOCOL_VERSION;
550   if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
551                                       &v_BYTE))
552     goto oom;
553
554   v_UINT32 = 0; /* body length */
555   if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
556                                       &v_UINT32))
557     goto oom;
558
559   v_UINT32 = 0; /* serial */
560   if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_UINT32,
561                                       &v_UINT32))
562     goto oom;
563
564   if (!_dbus_type_writer_recurse (&writer, DBUS_TYPE_ARRAY,
565                                   &_dbus_header_signature_str,
566                                   FIELDS_ARRAY_SIGNATURE_OFFSET,
567                                   &array))
568     goto oom;
569
570   /* Marshal all the fields (Marshall Fields?) */
571
572   if (path != NULL)
573     {
574       if (!write_basic_field (&array,
575                               DBUS_HEADER_FIELD_PATH,
576                               DBUS_TYPE_OBJECT_PATH,
577                               &path))
578         goto oom;
579     }
580
581   if (destination != NULL)
582     {
583       if (!write_basic_field (&array,
584                               DBUS_HEADER_FIELD_DESTINATION,
585                               DBUS_TYPE_STRING,
586                               &destination))
587         goto oom;
588     }
589
590   if (interface != NULL)
591     {
592       if (!write_basic_field (&array,
593                               DBUS_HEADER_FIELD_INTERFACE,
594                               DBUS_TYPE_STRING,
595                               &interface))
596         goto oom;
597     }
598
599   if (member != NULL)
600     {
601       if (!write_basic_field (&array,
602                               DBUS_HEADER_FIELD_MEMBER,
603                               DBUS_TYPE_STRING,
604                               &member))
605         goto oom;
606     }
607
608   if (error_name != NULL)
609     {
610       if (!write_basic_field (&array,
611                               DBUS_HEADER_FIELD_ERROR_NAME,
612                               DBUS_TYPE_STRING,
613                               &error_name))
614         goto oom;
615     }
616
617   if (!_dbus_type_writer_unrecurse (&writer, &array))
618     goto oom;
619
620   correct_header_padding (header);
621
622   return TRUE;
623
624  oom:
625   _dbus_string_delete (&header->data, 0,
626                        _dbus_string_get_length (&header->data) - header->padding);
627   correct_header_padding (header);
628
629   return FALSE;
630 }
631
632 /**
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.
637  *
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
647  */
648 dbus_bool_t
649 _dbus_header_have_message_untrusted (int                max_message_length,
650                                      DBusValidity      *validity,
651                                      int               *byte_order,
652                                      int               *fields_array_len,
653                                      int               *header_len,
654                                      int               *body_len,
655                                      const DBusString  *str,
656                                      int                start,
657                                      int                len)
658
659 {
660   dbus_uint32_t header_len_unsigned;
661   dbus_uint32_t fields_array_len_unsigned;
662   dbus_uint32_t body_len_unsigned;
663
664   _dbus_assert (start >= 0);
665   _dbus_assert (start < _DBUS_INT_MAX / 2);
666   _dbus_assert (len >= 0);
667
668   _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
669
670   *byte_order = _dbus_string_get_byte (str, start + BYTE_ORDER_OFFSET);
671
672   if (*byte_order != DBUS_LITTLE_ENDIAN && *byte_order != DBUS_BIG_ENDIAN)
673     {
674       *validity = DBUS_INVALID_BAD_BYTE_ORDER;
675       return FALSE;
676     }
677
678   _dbus_assert (FIELDS_ARRAY_LENGTH_OFFSET + 4 <= len);
679   fields_array_len_unsigned = _dbus_marshal_read_uint32 (str, start + FIELDS_ARRAY_LENGTH_OFFSET,
680                                                          *byte_order, NULL);
681
682   if (fields_array_len_unsigned > (unsigned) max_message_length)
683     {
684       *validity = DBUS_INVALID_INSANE_FIELDS_ARRAY_LENGTH;
685       return FALSE;
686     }
687
688   _dbus_assert (BODY_LENGTH_OFFSET + 4 < len);
689   body_len_unsigned = _dbus_marshal_read_uint32 (str, start + BODY_LENGTH_OFFSET,
690                                                  *byte_order, NULL);
691
692   if (body_len_unsigned > (unsigned) max_message_length)
693     {
694       *validity = DBUS_INVALID_INSANE_BODY_LENGTH;
695       return FALSE;
696     }
697
698   header_len_unsigned = FIRST_FIELD_OFFSET + fields_array_len_unsigned;
699   header_len_unsigned = _DBUS_ALIGN_VALUE (header_len_unsigned, 8);
700
701   /* overflow should be impossible since the lengths aren't allowed to
702    * be huge.
703    */
704   _dbus_assert (max_message_length < _DBUS_INT_MAX / 2);
705   if (body_len_unsigned + header_len_unsigned > (unsigned) max_message_length)
706     {
707       *validity = DBUS_INVALID_MESSAGE_TOO_LONG;
708       return FALSE;
709     }
710
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);
714
715   *body_len = body_len_unsigned;
716   *fields_array_len = fields_array_len_unsigned;
717   *header_len = header_len_unsigned;
718
719   *validity = DBUS_VALID;
720
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);
724
725   return (body_len_unsigned + header_len_unsigned) <= (unsigned) len;
726 }
727
728 static DBusValidity
729 check_mandatory_fields (DBusHeader *header)
730 {
731 #define REQUIRE_FIELD(name) do { if (header->fields[DBUS_HEADER_FIELD_##name].value_pos < 0) return DBUS_INVALID_MISSING_##name; } while (0)
732
733   switch (_dbus_header_get_message_type (header))
734     {
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);
741       break;
742     case DBUS_MESSAGE_TYPE_ERROR:
743       REQUIRE_FIELD (ERROR_NAME);
744       REQUIRE_FIELD (REPLY_SERIAL);
745       break;
746     case DBUS_MESSAGE_TYPE_METHOD_RETURN:
747       REQUIRE_FIELD (REPLY_SERIAL);
748       break;
749     default:
750       /* other message types allowed but ignored */
751       break;
752     }
753
754   return DBUS_VALID;
755 }
756
757 static DBusValidity
758 load_and_validate_field (DBusHeader     *header,
759                          int             field,
760                          DBusTypeReader *variant_reader)
761 {
762   int type;
763   int expected_type;
764   const DBusString *value_str;
765   int value_pos;
766   dbus_uint32_t v_UINT32;
767   int bad_string_code;
768   dbus_bool_t (* string_validation_func) (const DBusString *str,
769                                           int start, int len);
770
771   /* Supposed to have been checked already */
772   _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
773   _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
774
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);
777
778   _dbus_assert (_dbus_header_field_types[field].code == field);
779
780   expected_type = EXPECTED_TYPE_OF_FIELD (field);
781   if (type != expected_type)
782     {
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;
786     }
787
788   /* If the field was provided twice, we aren't happy */
789   if (header->fields[field].value_pos >= 0)
790     {
791       _dbus_verbose ("Header field %d seen a second time\n", field);
792       return DBUS_INVALID_HEADER_FIELD_APPEARS_TWICE;
793     }
794
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);
798
799   string_validation_func = NULL;
800
801   /* make compiler happy that all this is initialized */
802   v_UINT32 = 0;
803   value_str = NULL;
804   value_pos = -1;
805   bad_string_code = DBUS_VALID;
806
807   if (expected_type == DBUS_TYPE_UINT32)
808     {
809       _dbus_header_get_field_basic (header, field, expected_type,
810                                     &v_UINT32);
811     }
812   else if (expected_type == DBUS_TYPE_STRING ||
813            expected_type == DBUS_TYPE_OBJECT_PATH ||
814            expected_type == DBUS_TYPE_SIGNATURE)
815     {
816       _dbus_header_get_field_raw (header, field,
817                                   &value_str, &value_pos);
818     }
819   else
820     {
821       _dbus_assert_not_reached ("none of the known fields should have this type");
822     }
823
824   switch (field)
825     {
826     case DBUS_HEADER_FIELD_DESTINATION:
827       string_validation_func = _dbus_validate_service;
828       bad_string_code = DBUS_INVALID_BAD_DESTINATION;
829       break;
830     case DBUS_HEADER_FIELD_INTERFACE:
831       string_validation_func = _dbus_validate_interface;
832       bad_string_code = DBUS_INVALID_BAD_INTERFACE;
833
834       if (_dbus_string_equal_substring (&_dbus_local_interface_str,
835                                         0,
836                                         _dbus_string_get_length (&_dbus_local_interface_str),
837                                         value_str, value_pos))
838         {
839           _dbus_verbose ("Message is on the local interface\n");
840           return DBUS_INVALID_USES_LOCAL_INTERFACE;
841         }
842       break;
843
844     case DBUS_HEADER_FIELD_MEMBER:
845       string_validation_func = _dbus_validate_member;
846       bad_string_code = DBUS_INVALID_BAD_MEMBER;
847       break;
848
849     case DBUS_HEADER_FIELD_ERROR_NAME:
850       string_validation_func = _dbus_validate_error_name;
851       bad_string_code = DBUS_INVALID_BAD_ERROR_NAME;
852       break;
853
854     case DBUS_HEADER_FIELD_SENDER:
855       string_validation_func = _dbus_validate_service;
856       bad_string_code = DBUS_INVALID_BAD_SENDER;
857       break;
858
859     case DBUS_HEADER_FIELD_PATH:
860       /* OBJECT_PATH was validated generically due to its type */
861       string_validation_func = NULL;
862
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,
867                                         0,
868                                         _dbus_string_get_length (&_dbus_local_path_str),
869                                         value_str, value_pos))
870         {
871           _dbus_verbose ("Message is from the local path\n");
872           return DBUS_INVALID_USES_LOCAL_PATH;
873         }
874       break;
875
876     case DBUS_HEADER_FIELD_REPLY_SERIAL:
877       /* Can't be 0 */
878       if (v_UINT32 == 0)
879         {
880           return DBUS_INVALID_BAD_SERIAL;
881         }
882       break;
883
884     case DBUS_HEADER_FIELD_SIGNATURE:
885       /* SIGNATURE validated generically due to its type */
886       string_validation_func = NULL;
887       break;
888
889     default:
890       _dbus_assert_not_reached ("unknown field shouldn't be seen here");
891       break;
892     }
893
894   if (string_validation_func)
895     {
896       dbus_uint32_t len;
897
898       _dbus_assert (bad_string_code != DBUS_VALID);
899
900       len = _dbus_marshal_read_uint32 (value_str, value_pos,
901                                        header->byte_order, NULL);
902
903       if (!(*string_validation_func) (value_str, value_pos + 4, len))
904         return bad_string_code;
905     }
906
907   return DBUS_VALID;
908 }
909
910 /**
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
916  * invalid.
917  *
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
921  * already done.
922  *
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
933  */
934 dbus_bool_t
935 _dbus_header_load_untrusted (DBusHeader       *header,
936                              DBusValidity     *validity,
937                              int               byte_order,
938                              int               fields_array_len,
939                              int               header_len,
940                              int               body_len,
941                              const DBusString *str,
942                              int               start,
943                              int               len)
944 {
945   int leftover;
946   DBusValidity v;
947   DBusTypeReader reader;
948   DBusTypeReader array_reader;
949   unsigned char v_byte;
950   dbus_uint32_t v_uint32;
951   dbus_uint32_t serial;
952   int padding_start;
953   int padding_len;
954   int i;
955
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);
959
960   if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
961     {
962       _dbus_verbose ("Failed to copy buffer into new header\n");
963       *validity = DBUS_VALID;
964       return FALSE;
965     }
966
967   v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
968                                        byte_order,
969                                        &leftover,
970                                        str, start, len);
971
972   if (v != DBUS_VALID)
973     {
974       *validity = v;
975       goto invalid;
976     }
977
978   _dbus_assert (leftover < len);
979
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);
984
985   if (!_dbus_string_validate_nul (str, padding_start, padding_len))
986     {
987       *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
988       goto invalid;
989     }
990
991   header->padding = padding_len;
992
993   /* We now know the data is well-formed, but we have to check that
994    * it's valid.
995    */
996
997   _dbus_type_reader_init (&reader,
998                           byte_order,
999                           &_dbus_header_signature_str, 0,
1000                           str, start);
1001
1002   /* BYTE ORDER */
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);
1007
1008   _dbus_assert (v_byte == byte_order);
1009
1010   /* MESSAGE TYPE */
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);
1015
1016   /* unknown message types are supposed to be ignored, so only validation here is
1017    * that it isn't invalid
1018    */
1019   if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1020     {
1021       *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1022       goto invalid;
1023     }
1024
1025   /* FLAGS */
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);
1030
1031   /* unknown flags should be ignored */
1032
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);
1038
1039   if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1040     {
1041       *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1042       goto invalid;
1043     }
1044
1045   /* BODY LENGTH */
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);
1050
1051   _dbus_assert (body_len == (signed) v_uint32);
1052
1053   /* SERIAL */
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);
1058
1059   if (serial == 0)
1060     {
1061       *validity = DBUS_INVALID_BAD_SERIAL;
1062       goto invalid;
1063     }
1064
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);
1067
1068   _dbus_type_reader_recurse (&reader, &array_reader);
1069   while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1070     {
1071       DBusTypeReader struct_reader;
1072       DBusTypeReader variant_reader;
1073       unsigned char field_code;
1074
1075       _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT);
1076
1077       _dbus_type_reader_recurse (&array_reader, &struct_reader);
1078
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);
1082
1083       if (field_code == DBUS_HEADER_FIELD_INVALID)
1084         {
1085           _dbus_verbose ("invalid header field code\n");
1086           *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1087           goto invalid;
1088         }
1089
1090       if (field_code > DBUS_HEADER_FIELD_LAST)
1091         {
1092           _dbus_verbose ("unknown header field code %d, skipping\n",
1093                          field_code);
1094           goto next_field;
1095         }
1096
1097       _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT);
1098       _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1099
1100       v = load_and_validate_field (header, field_code, &variant_reader);
1101       if (v != DBUS_VALID)
1102         {
1103           _dbus_verbose ("Field %d was invalid\n", field_code);
1104           *validity = v;
1105           goto invalid;
1106         }
1107
1108     next_field:
1109       _dbus_type_reader_next (&array_reader);
1110     }
1111
1112   /* Anything we didn't fill in is now known not to exist */
1113   i = 0;
1114   while (i <= DBUS_HEADER_FIELD_LAST)
1115     {
1116       if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1117         header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1118       ++i;
1119     }
1120
1121   v = check_mandatory_fields (header);
1122   if (v != DBUS_VALID)
1123     {
1124       _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1125       *validity = v;
1126       goto invalid;
1127     }
1128
1129   *validity = DBUS_VALID;
1130   return TRUE;
1131
1132  invalid:
1133   _dbus_string_set_length (&header->data, 0);
1134   return FALSE;
1135 }
1136
1137 /**
1138  * Fills in the correct body length.
1139  *
1140  * @param header the header
1141  * @param body_len the length of the body
1142  */
1143 void
1144 _dbus_header_update_lengths (DBusHeader *header,
1145                              int         body_len)
1146 {
1147   _dbus_marshal_set_uint32 (&header->data,
1148                             BODY_LENGTH_OFFSET,
1149                             body_len,
1150                             header->byte_order);
1151 }
1152
1153 static dbus_bool_t
1154 find_field_for_modification (DBusHeader     *header,
1155                              int             field,
1156                              DBusTypeReader *reader,
1157                              DBusTypeReader *realign_root)
1158 {
1159   dbus_bool_t retval;
1160
1161   retval = FALSE;
1162
1163   _dbus_type_reader_init (realign_root,
1164                           header->byte_order,
1165                           &_dbus_header_signature_str,
1166                           FIELDS_ARRAY_SIGNATURE_OFFSET,
1167                           &header->data,
1168                           FIELDS_ARRAY_LENGTH_OFFSET);
1169
1170   _dbus_type_reader_recurse (realign_root, reader);
1171
1172   while (_dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID)
1173     {
1174       DBusTypeReader sub;
1175       unsigned char field_code;
1176
1177       _dbus_type_reader_recurse (reader, &sub);
1178
1179       _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
1180       _dbus_type_reader_read_basic (&sub, &field_code);
1181
1182       if (field_code == (unsigned) field)
1183         {
1184           _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_STRUCT);
1185           retval = TRUE;
1186           goto done;
1187         }
1188
1189       _dbus_type_reader_next (reader);
1190     }
1191
1192  done:
1193   return retval;
1194 }
1195
1196 /**
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.
1200  *
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
1206  */
1207 dbus_bool_t
1208 _dbus_header_set_field_basic (DBusHeader       *header,
1209                               int               field,
1210                               int               type,
1211                               const void       *value)
1212 {
1213   _dbus_return_val_if_fail (field <= DBUS_HEADER_FIELD_LAST, FALSE);
1214
1215   if (!reserve_header_padding (header))
1216     return FALSE;
1217
1218   /* If the field exists we set, otherwise we append */
1219   if (_dbus_header_cache_check (header, field))
1220     {
1221       DBusTypeReader reader;
1222       DBusTypeReader realign_root;
1223
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");
1227
1228       if (!set_basic_field (&reader, field, type, value, &realign_root))
1229         return FALSE;
1230     }
1231   else
1232     {
1233       DBusTypeWriter writer;
1234       DBusTypeWriter array;
1235
1236       _dbus_type_writer_init_values_only (&writer,
1237                                           header->byte_order,
1238                                           &_dbus_header_signature_str,
1239                                           FIELDS_ARRAY_SIGNATURE_OFFSET,
1240                                           &header->data,
1241                                           FIELDS_ARRAY_LENGTH_OFFSET);
1242
1243       /* recurse into array without creating a new length, and jump to
1244        * end of array.
1245        */
1246       if (!_dbus_type_writer_append_array (&writer,
1247                                            &_dbus_header_signature_str,
1248                                            FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET,
1249                                            &array))
1250         _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1251
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));
1255
1256       if (!write_basic_field (&array,
1257                               field, type, value))
1258         return FALSE;
1259
1260       if (!_dbus_type_writer_unrecurse (&writer, &array))
1261         _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1262     }
1263
1264   correct_header_padding (header);
1265
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.
1269    */
1270   _dbus_header_cache_invalidate_all (header);
1271
1272   return TRUE;
1273 }
1274
1275 /**
1276  * Gets the value of a field with basic type. If the field
1277  * doesn't exist, returns #FALSE, otherwise returns #TRUE.
1278  *
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
1284  */
1285 dbus_bool_t
1286 _dbus_header_get_field_basic (DBusHeader    *header,
1287                               int            field,
1288                               int            type,
1289                               void          *value)
1290 {
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
1297    */
1298   _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1299
1300   if (!_dbus_header_cache_check (header, field))
1301     return FALSE;
1302
1303   _dbus_assert (header->fields[field].value_pos >= 0);
1304
1305   _dbus_marshal_read_basic (&header->data,
1306                             header->fields[field].value_pos,
1307                             type, value, header->byte_order,
1308                             NULL);
1309
1310   return TRUE;
1311 }
1312
1313 /**
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
1318  * itself.
1319  *
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
1325  */
1326 dbus_bool_t
1327 _dbus_header_get_field_raw (DBusHeader        *header,
1328                             int                field,
1329                             const DBusString **str,
1330                             int               *pos)
1331 {
1332   if (!_dbus_header_cache_check (header, field))
1333     return FALSE;
1334
1335   if (str)
1336     *str = &header->data;
1337   if (pos)
1338     *pos = header->fields[field].value_pos;
1339
1340   return TRUE;
1341 }
1342
1343 /**
1344  * Deletes a field, if it exists.
1345  *
1346  * @param header the header
1347  * @param field the field to delete
1348  * @returns #FALSE if no memory
1349  */
1350 dbus_bool_t
1351 _dbus_header_delete_field (DBusHeader *header,
1352                            int         field)
1353 {
1354   DBusTypeReader reader;
1355   DBusTypeReader realign_root;
1356
1357   if (_dbus_header_cache_known_nonexistent (header, field))
1358     return TRUE; /* nothing to do */
1359
1360   /* Scan to the field we want, delete and realign, reappend
1361    * padding. Field may turn out not to exist.
1362    */
1363   if (!find_field_for_modification (header, field,
1364                                     &reader, &realign_root))
1365     return TRUE; /* nothing to do */
1366
1367   if (!reserve_header_padding (header))
1368     return FALSE;
1369
1370   if (!_dbus_type_reader_delete (&reader,
1371                                  &realign_root))
1372     return FALSE;
1373
1374   correct_header_padding (header);
1375
1376   _dbus_header_cache_invalidate_all (header);
1377
1378   _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1379
1380   return TRUE;
1381 }
1382
1383 /**
1384  * Toggles a message flag bit, turning on the bit if value = TRUE and
1385  * flipping it off if value = FALSE.
1386  *
1387  * @param header the header
1388  * @param flag the message flag to toggle
1389  * @param value toggle on or off
1390  */
1391 void
1392 _dbus_header_toggle_flag (DBusHeader   *header,
1393                           dbus_uint32_t flag,
1394                           dbus_bool_t   value)
1395 {
1396   unsigned char *flags_p;
1397
1398   flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1);
1399
1400   if (value)
1401     *flags_p |= flag;
1402   else
1403     *flags_p &= ~flag;
1404 }
1405
1406 /**
1407  * Gets a message flag bit, returning TRUE if the bit is set.
1408  *
1409  * @param header the header
1410  * @param flag the message flag to get
1411  * @returns #TRUE if the flag is set
1412  */
1413 dbus_bool_t
1414 _dbus_header_get_flag (DBusHeader   *header,
1415                        dbus_uint32_t flag)
1416 {
1417   const unsigned char *flags_p;
1418
1419   flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1);
1420
1421   return (*flags_p & flag) != 0;
1422 }
1423
1424 /** @} */
1425
1426 #ifdef DBUS_BUILD_TESTS
1427 #include "dbus-test.h"
1428 #include <stdio.h>
1429
1430 dbus_bool_t
1431 _dbus_marshal_header_test (void)
1432 {
1433
1434   return TRUE;
1435 }
1436
1437 #endif /* DBUS_BUILD_TESTS */