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