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