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