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