2005-05-25 Colin Walters <walters@verbum.org>
[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_VALID, then there wasn't
930  * enough memory.  If it returns #FALSE and *validity != #DBUS_VALID
931  * then the data was invalid.
932  *
933  * The byte_order, fields_array_len, and body_len args should be from
934  * _dbus_header_have_message_untrusted(). Validation performed in
935  * _dbus_header_have_message_untrusted() is assumed to have been
936  * already done.
937  *
938  * @param header the header (must be initialized)
939  * @param mode whether to do validation
940  * @param validity return location for invalidity reason
941  * @param byte_order byte order from header
942  * @param fields_array_len claimed length of fields array
943  * @param body_len claimed length of body
944  * @param header_len claimed length of header
945  * @param str a string
946  * @param start start of header, 8-aligned
947  * @param len length of string to look at
948  * @returns #FALSE if no memory or data was invalid, #TRUE otherwise
949  */
950 dbus_bool_t
951 _dbus_header_load (DBusHeader        *header,
952                    DBusValidationMode mode,
953                    DBusValidity      *validity,
954                    int                byte_order,
955                    int                fields_array_len,
956                    int                header_len,
957                    int                body_len,
958                    const DBusString  *str,
959                    int                start,
960                    int                len)
961 {
962   int leftover;
963   DBusValidity v;
964   DBusTypeReader reader;
965   DBusTypeReader array_reader;
966   unsigned char v_byte;
967   dbus_uint32_t v_uint32;
968   dbus_uint32_t serial;
969   int padding_start;
970   int padding_len;
971   int i;
972
973   _dbus_assert (start == (int) _DBUS_ALIGN_VALUE (start, 8));
974   _dbus_assert (header_len <= len);
975   _dbus_assert (_dbus_string_get_length (&header->data) == 0);
976
977   if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
978     {
979       _dbus_verbose ("Failed to copy buffer into new header\n");
980       *validity = DBUS_VALID;
981       return FALSE;
982     }
983
984   if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
985     {
986       leftover = len - header_len - body_len - start;
987     }
988   else
989     {
990       v = _dbus_validate_body_with_reason (&_dbus_header_signature_str, 0,
991                                            byte_order,
992                                            &leftover,
993                                            str, start, len);
994       
995       if (v != DBUS_VALID)
996         {
997           *validity = v;
998           goto invalid;
999         }
1000     }
1001
1002   _dbus_assert (leftover < len);
1003
1004   padding_len = header_len - (FIRST_FIELD_OFFSET + fields_array_len);
1005   padding_start = start + FIRST_FIELD_OFFSET + fields_array_len;
1006   _dbus_assert (start + header_len == (int) _DBUS_ALIGN_VALUE (padding_start, 8));
1007   _dbus_assert (start + header_len == padding_start + padding_len);
1008
1009   if (mode != DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1010     {
1011       if (!_dbus_string_validate_nul (str, padding_start, padding_len))
1012         {
1013           *validity = DBUS_INVALID_ALIGNMENT_PADDING_NOT_NUL;
1014           goto invalid;
1015         }
1016     }
1017
1018   header->padding = padding_len;
1019
1020   if (mode == DBUS_VALIDATION_MODE_WE_TRUST_THIS_DATA_ABSOLUTELY)
1021     {
1022       *validity = DBUS_VALID;
1023       return TRUE;
1024     }
1025
1026   /* We now know the data is well-formed, but we have to check that
1027    * it's valid.
1028    */
1029
1030   _dbus_type_reader_init (&reader,
1031                           byte_order,
1032                           &_dbus_header_signature_str, 0,
1033                           str, start);
1034
1035   /* BYTE ORDER */
1036   _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1037   _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BYTE_ORDER_OFFSET);
1038   _dbus_type_reader_read_basic (&reader, &v_byte);
1039   _dbus_type_reader_next (&reader);
1040
1041   _dbus_assert (v_byte == byte_order);
1042
1043   /* MESSAGE TYPE */
1044   _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1045   _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == TYPE_OFFSET);
1046   _dbus_type_reader_read_basic (&reader, &v_byte);
1047   _dbus_type_reader_next (&reader);
1048
1049   /* unknown message types are supposed to be ignored, so only validation here is
1050    * that it isn't invalid
1051    */
1052   if (v_byte == DBUS_MESSAGE_TYPE_INVALID)
1053     {
1054       *validity = DBUS_INVALID_BAD_MESSAGE_TYPE;
1055       goto invalid;
1056     }
1057
1058   /* FLAGS */
1059   _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1060   _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FLAGS_OFFSET);
1061   _dbus_type_reader_read_basic (&reader, &v_byte);
1062   _dbus_type_reader_next (&reader);
1063
1064   /* unknown flags should be ignored */
1065
1066   /* PROTOCOL VERSION */
1067   _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_BYTE);
1068   _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == VERSION_OFFSET);
1069   _dbus_type_reader_read_basic (&reader, &v_byte);
1070   _dbus_type_reader_next (&reader);
1071
1072   if (v_byte != DBUS_MAJOR_PROTOCOL_VERSION)
1073     {
1074       *validity = DBUS_INVALID_BAD_PROTOCOL_VERSION;
1075       goto invalid;
1076     }
1077
1078   /* BODY LENGTH */
1079   _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
1080   _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == BODY_LENGTH_OFFSET);
1081   _dbus_type_reader_read_basic (&reader, &v_uint32);
1082   _dbus_type_reader_next (&reader);
1083
1084   _dbus_assert (body_len == (signed) v_uint32);
1085
1086   /* SERIAL */
1087   _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_UINT32);
1088   _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == SERIAL_OFFSET);
1089   _dbus_type_reader_read_basic (&reader, &serial);
1090   _dbus_type_reader_next (&reader);
1091
1092   if (serial == 0)
1093     {
1094       *validity = DBUS_INVALID_BAD_SERIAL;
1095       goto invalid;
1096     }
1097
1098   _dbus_assert (_dbus_type_reader_get_current_type (&reader) == DBUS_TYPE_ARRAY);
1099   _dbus_assert (_dbus_type_reader_get_value_pos (&reader) == FIELDS_ARRAY_LENGTH_OFFSET);
1100
1101   _dbus_type_reader_recurse (&reader, &array_reader);
1102   while (_dbus_type_reader_get_current_type (&array_reader) != DBUS_TYPE_INVALID)
1103     {
1104       DBusTypeReader struct_reader;
1105       DBusTypeReader variant_reader;
1106       unsigned char field_code;
1107
1108       _dbus_assert (_dbus_type_reader_get_current_type (&array_reader) == DBUS_TYPE_STRUCT);
1109
1110       _dbus_type_reader_recurse (&array_reader, &struct_reader);
1111
1112       _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_BYTE);
1113       _dbus_type_reader_read_basic (&struct_reader, &field_code);
1114       _dbus_type_reader_next (&struct_reader);
1115
1116       if (field_code == DBUS_HEADER_FIELD_INVALID)
1117         {
1118           _dbus_verbose ("invalid header field code\n");
1119           *validity = DBUS_INVALID_HEADER_FIELD_CODE;
1120           goto invalid;
1121         }
1122
1123       if (field_code > DBUS_HEADER_FIELD_LAST)
1124         {
1125           _dbus_verbose ("unknown header field code %d, skipping\n",
1126                          field_code);
1127           goto next_field;
1128         }
1129
1130       _dbus_assert (_dbus_type_reader_get_current_type (&struct_reader) == DBUS_TYPE_VARIANT);
1131       _dbus_type_reader_recurse (&struct_reader, &variant_reader);
1132
1133       v = load_and_validate_field (header, field_code, &variant_reader);
1134       if (v != DBUS_VALID)
1135         {
1136           _dbus_verbose ("Field %d was invalid\n", field_code);
1137           *validity = v;
1138           goto invalid;
1139         }
1140
1141     next_field:
1142       _dbus_type_reader_next (&array_reader);
1143     }
1144
1145   /* Anything we didn't fill in is now known not to exist */
1146   i = 0;
1147   while (i <= DBUS_HEADER_FIELD_LAST)
1148     {
1149       if (header->fields[i].value_pos == _DBUS_HEADER_FIELD_VALUE_UNKNOWN)
1150         header->fields[i].value_pos = _DBUS_HEADER_FIELD_VALUE_NONEXISTENT;
1151       ++i;
1152     }
1153
1154   v = check_mandatory_fields (header);
1155   if (v != DBUS_VALID)
1156     {
1157       _dbus_verbose ("Mandatory fields were missing, code %d\n", v);
1158       *validity = v;
1159       goto invalid;
1160     }
1161
1162   *validity = DBUS_VALID;
1163   return TRUE;
1164
1165  invalid:
1166   _dbus_string_set_length (&header->data, 0);
1167   return FALSE;
1168 }
1169
1170 /**
1171  * Fills in the correct body length.
1172  *
1173  * @param header the header
1174  * @param body_len the length of the body
1175  */
1176 void
1177 _dbus_header_update_lengths (DBusHeader *header,
1178                              int         body_len)
1179 {
1180   _dbus_marshal_set_uint32 (&header->data,
1181                             BODY_LENGTH_OFFSET,
1182                             body_len,
1183                             header->byte_order);
1184 }
1185
1186 static dbus_bool_t
1187 find_field_for_modification (DBusHeader     *header,
1188                              int             field,
1189                              DBusTypeReader *reader,
1190                              DBusTypeReader *realign_root)
1191 {
1192   dbus_bool_t retval;
1193
1194   retval = FALSE;
1195
1196   _dbus_type_reader_init (realign_root,
1197                           header->byte_order,
1198                           &_dbus_header_signature_str,
1199                           FIELDS_ARRAY_SIGNATURE_OFFSET,
1200                           &header->data,
1201                           FIELDS_ARRAY_LENGTH_OFFSET);
1202
1203   _dbus_type_reader_recurse (realign_root, reader);
1204
1205   while (_dbus_type_reader_get_current_type (reader) != DBUS_TYPE_INVALID)
1206     {
1207       DBusTypeReader sub;
1208       unsigned char field_code;
1209
1210       _dbus_type_reader_recurse (reader, &sub);
1211
1212       _dbus_assert (_dbus_type_reader_get_current_type (&sub) == DBUS_TYPE_BYTE);
1213       _dbus_type_reader_read_basic (&sub, &field_code);
1214
1215       if (field_code == (unsigned) field)
1216         {
1217           _dbus_assert (_dbus_type_reader_get_current_type (reader) == DBUS_TYPE_STRUCT);
1218           retval = TRUE;
1219           goto done;
1220         }
1221
1222       _dbus_type_reader_next (reader);
1223     }
1224
1225  done:
1226   return retval;
1227 }
1228
1229 /**
1230  * Sets the value of a field with basic type. If the value is a string
1231  * value, it isn't allowed to be #NULL. If the field doesn't exist,
1232  * it will be created.
1233  *
1234  * @param header the header
1235  * @param field the field to set
1236  * @param type the type of the value
1237  * @param value the value as for _dbus_marshal_set_basic()
1238  * @returns #FALSE if no memory
1239  */
1240 dbus_bool_t
1241 _dbus_header_set_field_basic (DBusHeader       *header,
1242                               int               field,
1243                               int               type,
1244                               const void       *value)
1245 {
1246   _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
1247
1248   if (!reserve_header_padding (header))
1249     return FALSE;
1250
1251   /* If the field exists we set, otherwise we append */
1252   if (_dbus_header_cache_check (header, field))
1253     {
1254       DBusTypeReader reader;
1255       DBusTypeReader realign_root;
1256
1257       if (!find_field_for_modification (header, field,
1258                                         &reader, &realign_root))
1259         _dbus_assert_not_reached ("field was marked present in cache but wasn't found");
1260
1261       if (!set_basic_field (&reader, field, type, value, &realign_root))
1262         return FALSE;
1263     }
1264   else
1265     {
1266       DBusTypeWriter writer;
1267       DBusTypeWriter array;
1268
1269       _dbus_type_writer_init_values_only (&writer,
1270                                           header->byte_order,
1271                                           &_dbus_header_signature_str,
1272                                           FIELDS_ARRAY_SIGNATURE_OFFSET,
1273                                           &header->data,
1274                                           FIELDS_ARRAY_LENGTH_OFFSET);
1275
1276       /* recurse into array without creating a new length, and jump to
1277        * end of array.
1278        */
1279       if (!_dbus_type_writer_append_array (&writer,
1280                                            &_dbus_header_signature_str,
1281                                            FIELDS_ARRAY_ELEMENT_SIGNATURE_OFFSET,
1282                                            &array))
1283         _dbus_assert_not_reached ("recurse into ARRAY should not have used memory");
1284
1285       _dbus_assert (array.u.array.len_pos == FIELDS_ARRAY_LENGTH_OFFSET);
1286       _dbus_assert (array.u.array.start_pos == FIRST_FIELD_OFFSET);
1287       _dbus_assert (array.value_pos == HEADER_END_BEFORE_PADDING (header));
1288
1289       if (!write_basic_field (&array,
1290                               field, type, value))
1291         return FALSE;
1292
1293       if (!_dbus_type_writer_unrecurse (&writer, &array))
1294         _dbus_assert_not_reached ("unrecurse from ARRAY should not have used memory");
1295     }
1296
1297   correct_header_padding (header);
1298
1299   /* We could be smarter about this (only invalidate fields after the
1300    * one we modified, or even only if the one we modified changed
1301    * length). But this hack is a start.
1302    */
1303   _dbus_header_cache_invalidate_all (header);
1304
1305   return TRUE;
1306 }
1307
1308 /**
1309  * Gets the value of a field with basic type. If the field
1310  * doesn't exist, returns #FALSE, otherwise returns #TRUE.
1311  *
1312  * @param header the header
1313  * @param field the field to get
1314  * @param type the type of the value
1315  * @param value the value as for _dbus_marshal_read_basic()
1316  * @returns #FALSE if the field doesn't exist
1317  */
1318 dbus_bool_t
1319 _dbus_header_get_field_basic (DBusHeader    *header,
1320                               int            field,
1321                               int            type,
1322                               void          *value)
1323 {
1324   _dbus_assert (field != DBUS_HEADER_FIELD_INVALID);
1325   _dbus_assert (field <= DBUS_HEADER_FIELD_LAST);
1326   _dbus_assert (_dbus_header_field_types[field].code == field);
1327   /* in light of this you might ask why the type is passed in;
1328    * the only rationale I can think of is so the caller has
1329    * to specify its expectation and breaks if we change it
1330    */
1331   _dbus_assert (type == EXPECTED_TYPE_OF_FIELD (field));
1332
1333   if (!_dbus_header_cache_check (header, field))
1334     return FALSE;
1335
1336   _dbus_assert (header->fields[field].value_pos >= 0);
1337
1338   _dbus_marshal_read_basic (&header->data,
1339                             header->fields[field].value_pos,
1340                             type, value, header->byte_order,
1341                             NULL);
1342
1343   return TRUE;
1344 }
1345
1346 /**
1347  * Gets the raw marshaled data for a field. If the field doesn't
1348  * exist, returns #FALSE, otherwise returns #TRUE.  Returns the start
1349  * of the marshaled data, i.e. usually the byte where the length
1350  * starts (for strings and arrays) or for basic types just the value
1351  * itself.
1352  *
1353  * @param header the header
1354  * @param field the field to get
1355  * @param str return location for the data string
1356  * @param pos return location for start of field value
1357  * @returns #FALSE if the field doesn't exist
1358  */
1359 dbus_bool_t
1360 _dbus_header_get_field_raw (DBusHeader        *header,
1361                             int                field,
1362                             const DBusString **str,
1363                             int               *pos)
1364 {
1365   if (!_dbus_header_cache_check (header, field))
1366     return FALSE;
1367
1368   if (str)
1369     *str = &header->data;
1370   if (pos)
1371     *pos = header->fields[field].value_pos;
1372
1373   return TRUE;
1374 }
1375
1376 /**
1377  * Deletes a field, if it exists.
1378  *
1379  * @param header the header
1380  * @param field the field to delete
1381  * @returns #FALSE if no memory
1382  */
1383 dbus_bool_t
1384 _dbus_header_delete_field (DBusHeader *header,
1385                            int         field)
1386 {
1387   DBusTypeReader reader;
1388   DBusTypeReader realign_root;
1389
1390   if (_dbus_header_cache_known_nonexistent (header, field))
1391     return TRUE; /* nothing to do */
1392
1393   /* Scan to the field we want, delete and realign, reappend
1394    * padding. Field may turn out not to exist.
1395    */
1396   if (!find_field_for_modification (header, field,
1397                                     &reader, &realign_root))
1398     return TRUE; /* nothing to do */
1399
1400   if (!reserve_header_padding (header))
1401     return FALSE;
1402
1403   if (!_dbus_type_reader_delete (&reader,
1404                                  &realign_root))
1405     return FALSE;
1406
1407   correct_header_padding (header);
1408
1409   _dbus_header_cache_invalidate_all (header);
1410
1411   _dbus_assert (!_dbus_header_cache_check (header, field)); /* Expensive assertion ... */
1412
1413   return TRUE;
1414 }
1415
1416 /**
1417  * Toggles a message flag bit, turning on the bit if value = TRUE and
1418  * flipping it off if value = FALSE.
1419  *
1420  * @param header the header
1421  * @param flag the message flag to toggle
1422  * @param value toggle on or off
1423  */
1424 void
1425 _dbus_header_toggle_flag (DBusHeader   *header,
1426                           dbus_uint32_t flag,
1427                           dbus_bool_t   value)
1428 {
1429   unsigned char *flags_p;
1430
1431   flags_p = _dbus_string_get_data_len (&header->data, FLAGS_OFFSET, 1);
1432
1433   if (value)
1434     *flags_p |= flag;
1435   else
1436     *flags_p &= ~flag;
1437 }
1438
1439 /**
1440  * Gets a message flag bit, returning TRUE if the bit is set.
1441  *
1442  * @param header the header
1443  * @param flag the message flag to get
1444  * @returns #TRUE if the flag is set
1445  */
1446 dbus_bool_t
1447 _dbus_header_get_flag (DBusHeader   *header,
1448                        dbus_uint32_t flag)
1449 {
1450   const unsigned char *flags_p;
1451
1452   flags_p = _dbus_string_get_const_data_len (&header->data, FLAGS_OFFSET, 1);
1453
1454   return (*flags_p & flag) != 0;
1455 }
1456
1457 /**
1458  * Swaps the header into the given order if required.
1459  *
1460  * @param header the header
1461  * @param new_order the new byte order
1462  */
1463 void
1464 _dbus_header_byteswap (DBusHeader *header,
1465                        int         new_order)
1466 {
1467   if (header->byte_order == new_order)
1468     return;
1469
1470   _dbus_marshal_byteswap (&_dbus_header_signature_str,
1471                           0, header->byte_order,
1472                           new_order,
1473                           &header->data, 0);
1474
1475   header->byte_order = new_order;
1476 }
1477
1478 /** @} */
1479
1480 #ifdef DBUS_BUILD_TESTS
1481 #include "dbus-test.h"
1482 #include <stdio.h>
1483
1484 dbus_bool_t
1485 _dbus_marshal_header_test (void)
1486 {
1487
1488   return TRUE;
1489 }
1490
1491 #endif /* DBUS_BUILD_TESTS */