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