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