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