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