[daemon-fix] Fixed sending daemon match rules for kdbus broadcasts
[platform/upstream/dbus.git] / dbus / dbus-marshal-header.c
index 3df1960..48151c6 100644 (file)
@@ -1,4 +1,4 @@
-/* -*- mode: C; c-file-style: "gnu" -*- */
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
 /* dbus-marshal-header.c  Managing marshaling/demarshaling of message headers
  *
  * Copyright (C) 2005  Red Hat, Inc.
  *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  *
  */
 
+#include <config.h>
+#include "dbus/dbus-shared.h"
 #include "dbus-marshal-header.h"
 #include "dbus-marshal-recursive.h"
 #include "dbus-marshal-byteswap.h"
@@ -66,8 +68,8 @@ _DBUS_STRING_DEFINE_STATIC(_dbus_local_path_str,       DBUS_PATH_LOCAL);
 
 typedef struct
 {
-  unsigned char code;
-  unsigned char type;
+  unsigned char code; /**< the field code */
+  unsigned char type; /**< the value type */
 } HeaderFieldType;
 
 static const HeaderFieldType
@@ -80,7 +82,8 @@ _dbus_header_field_types[DBUS_HEADER_FIELD_LAST+1] = {
   { DBUS_HEADER_FIELD_REPLY_SERIAL, DBUS_TYPE_UINT32 },
   { DBUS_HEADER_FIELD_DESTINATION, DBUS_TYPE_STRING },
   { DBUS_HEADER_FIELD_SENDER, DBUS_TYPE_STRING },
-  { DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE }
+  { DBUS_HEADER_FIELD_SIGNATURE, DBUS_TYPE_SIGNATURE },
+  { DBUS_HEADER_FIELD_UNIX_FDS, DBUS_TYPE_UINT32 }
 };
 
 /** Macro to look up the correct type for a field */
@@ -152,10 +155,6 @@ _dbus_header_cache_one (DBusHeader     *header,
                         int             field_code,
                         DBusTypeReader *variant_reader)
 {
-  int variant_type;
-
-  variant_type = _dbus_type_reader_get_current_type (variant_reader);
-
   header->fields[field_code].value_pos =
     _dbus_type_reader_get_value_pos (variant_reader);
 
@@ -166,6 +165,20 @@ _dbus_header_cache_one (DBusHeader     *header,
 }
 
 /**
+ * Returns the header's byte order.
+ *
+ * @param header the header
+ * @returns the byte order
+ */
+char
+_dbus_header_get_byte_order (const DBusHeader *header)
+{
+  _dbus_assert (_dbus_string_get_length (&header->data) > BYTE_ORDER_OFFSET);
+
+  return (char) _dbus_string_get_byte (&header->data, BYTE_ORDER_OFFSET);
+}
+
+/**
  * Revalidates the fields cache
  *
  * @param header the header
@@ -185,7 +198,7 @@ _dbus_header_cache_revalidate (DBusHeader *header)
     }
 
   _dbus_type_reader_init (&reader,
-                          header->byte_order,
+                          _dbus_header_get_byte_order (header),
                           &_dbus_header_signature_str,
                           FIELDS_ARRAY_SIGNATURE_OFFSET,
                           &header->data,
@@ -263,6 +276,7 @@ _dbus_header_cache_known_nonexistent (DBusHeader    *header,
  * Writes a struct of { byte, variant } with the given basic type.
  *
  * @param writer the writer (should be ready to write a struct)
+ * @param field the header field
  * @param type the type of the value
  * @param value the value as for _dbus_marshal_set_basic()
  * @returns #FALSE if no memory
@@ -323,6 +337,7 @@ write_basic_field (DBusTypeWriter *writer,
  * Sets a struct of { byte, variant } with the given basic type.
  *
  * @param reader the reader (should be iterating over the array pointing at the field to set)
+ * @param field the header field
  * @param type the type of the value
  * @param value the value as for _dbus_marshal_set_basic()
  * @param realign_root where to realign from
@@ -399,7 +414,7 @@ _dbus_header_set_serial (DBusHeader    *header,
   _dbus_marshal_set_uint32 (&header->data,
                             SERIAL_OFFSET,
                            serial,
-                            header->byte_order);
+                            _dbus_header_get_byte_order (header));
 }
 
 /**
@@ -413,7 +428,7 @@ _dbus_header_get_serial (DBusHeader *header)
 {
   return _dbus_marshal_read_uint32 (&header->data,
                                     SERIAL_OFFSET,
-                                    header->byte_order,
+                                    _dbus_header_get_byte_order (header),
                                     NULL);
 }
 
@@ -423,15 +438,12 @@ _dbus_header_get_serial (DBusHeader *header)
  * _dbus_header_create().
  *
  * @param header header to re-initialize
- * @param byte_order byte order of the header
  */
 void
-_dbus_header_reinit (DBusHeader *header,
-                     int         byte_order)
+_dbus_header_reinit (DBusHeader *header)
 {
   _dbus_string_set_length (&header->data, 0);
 
-  header->byte_order = byte_order;
   header->padding = 0;
 
   _dbus_header_cache_invalidate_all (header);
@@ -442,17 +454,15 @@ _dbus_header_reinit (DBusHeader *header,
  * to make the header valid, you have to call _dbus_header_create().
  *
  * @param header header to initialize
- * @param byte_order byte order of the header
  * @returns #FALSE if not enough memory
  */
 dbus_bool_t
-_dbus_header_init (DBusHeader *header,
-                   int         byte_order)
+_dbus_header_init (DBusHeader *header)
 {
   if (!_dbus_string_init_preallocated (&header->data, 32))
     return FALSE;
 
-  _dbus_header_reinit (header, byte_order);
+  _dbus_header_reinit (header);
 
   return TRUE;
 }
@@ -505,6 +515,7 @@ _dbus_header_copy (const DBusHeader *header,
  * sense, and passing them in will trigger an assertion failure.
  *
  * @param header the header
+ * @param byte_order byte order of the header
  * @param message_type the message type
  * @param destination destination field or #NULL
  * @param path path field or #NULL
@@ -515,6 +526,7 @@ _dbus_header_copy (const DBusHeader *header,
  */
 dbus_bool_t
 _dbus_header_create (DBusHeader  *header,
+                     int          byte_order,
                      int          message_type,
                      const char  *destination,
                      const char  *path,
@@ -527,6 +539,8 @@ _dbus_header_create (DBusHeader  *header,
   DBusTypeWriter writer;
   DBusTypeWriter array;
 
+  _dbus_assert (byte_order == DBUS_LITTLE_ENDIAN ||
+                byte_order == DBUS_BIG_ENDIAN);
   _dbus_assert (((interface || message_type != DBUS_MESSAGE_TYPE_SIGNAL) && member) ||
                 (error_name) ||
                 !(interface || member || error_name));
@@ -535,12 +549,12 @@ _dbus_header_create (DBusHeader  *header,
   if (!reserve_header_padding (header))
     return FALSE;
 
-  _dbus_type_writer_init_values_only (&writer, header->byte_order,
+  _dbus_type_writer_init_values_only (&writer, byte_order,
                                       &_dbus_header_signature_str, 0,
                                       &header->data,
                                       HEADER_END_BEFORE_PADDING (header));
 
-  v_BYTE = header->byte_order;
+  v_BYTE = byte_order;
   if (!_dbus_type_writer_write_basic (&writer, DBUS_TYPE_BYTE,
                                       &v_BYTE))
     goto oom;
@@ -891,6 +905,10 @@ load_and_validate_field (DBusHeader     *header,
         }
       break;
 
+    case DBUS_HEADER_FIELD_UNIX_FDS:
+      /* Every value makes sense */
+      break;
+
     case DBUS_HEADER_FIELD_SIGNATURE:
       /* SIGNATURE validated generically due to its type */
       string_validation_func = NULL;
@@ -908,7 +926,8 @@ load_and_validate_field (DBusHeader     *header,
       _dbus_assert (bad_string_code != DBUS_VALID);
 
       len = _dbus_marshal_read_uint32 (value_str, value_pos,
-                                       header->byte_order, NULL);
+                                       _dbus_header_get_byte_order (header),
+                                       NULL);
 
 #if 0
       _dbus_verbose ("Validating string header field; code %d if fails\n",
@@ -925,9 +944,10 @@ load_and_validate_field (DBusHeader     *header,
  * Creates a message header from potentially-untrusted data. The
  * return value is #TRUE if there was enough memory and the data was
  * valid. If it returns #TRUE, the header will be created. If it
- * returns #FALSE and *validity == #DBUS_VALID, then there wasn't
- * enough memory.  If it returns #FALSE and *validity != #DBUS_VALID
- * then the data was invalid.
+ * returns #FALSE and *validity == #DBUS_VALIDITY_UNKNOWN_OOM_ERROR, 
+ * then there wasn't enough memory.  If it returns #FALSE 
+ * and *validity != #DBUS_VALIDITY_UNKNOWN_OOM_ERROR then the data was 
+ * invalid.
  *
  * The byte_order, fields_array_len, and body_len args should be from
  * _dbus_header_have_message_untrusted(). Validation performed in
@@ -976,7 +996,7 @@ _dbus_header_load (DBusHeader        *header,
   if (!_dbus_string_copy_len (str, start, header_len, &header->data, 0))
     {
       _dbus_verbose ("Failed to copy buffer into new header\n");
-      *validity = DBUS_VALID;
+      *validity = DBUS_VALIDITY_UNKNOWN_OOM_ERROR;
       return FALSE;
     }
 
@@ -1179,9 +1199,22 @@ _dbus_header_update_lengths (DBusHeader *header,
   _dbus_marshal_set_uint32 (&header->data,
                             BODY_LENGTH_OFFSET,
                             body_len,
-                            header->byte_order);
+                            _dbus_header_get_byte_order (header));
 }
 
+/**
+ * Try to find the given field.
+ *
+ * @param header the header
+ * @param field the field code
+ * @param reader a type reader; on success this is left pointing at the struct
+ *  (uv) for the field, while on failure it is left pointing into empty space
+ *  at the end of the header fields
+ * @param realign_root another type reader; on success or failure it is left
+ *  pointing to the beginning of the array of fields (i.e. the thing that might
+ *  need realigning)
+ * @returns #TRUE on success
+ */
 static dbus_bool_t
 find_field_for_modification (DBusHeader     *header,
                              int             field,
@@ -1193,7 +1226,7 @@ find_field_for_modification (DBusHeader     *header,
   retval = FALSE;
 
   _dbus_type_reader_init (realign_root,
-                          header->byte_order,
+                          _dbus_header_get_byte_order (header),
                           &_dbus_header_signature_str,
                           FIELDS_ARRAY_SIGNATURE_OFFSET,
                           &header->data,
@@ -1266,7 +1299,7 @@ _dbus_header_set_field_basic (DBusHeader       *header,
       DBusTypeWriter array;
 
       _dbus_type_writer_init_values_only (&writer,
-                                          header->byte_order,
+                                          _dbus_header_get_byte_order (header),
                                           &_dbus_header_signature_str,
                                           FIELDS_ARRAY_SIGNATURE_OFFSET,
                                           &header->data,
@@ -1336,7 +1369,7 @@ _dbus_header_get_field_basic (DBusHeader    *header,
 
   _dbus_marshal_read_basic (&header->data,
                             header->fields[field].value_pos,
-                            type, value, header->byte_order,
+                            type, value, _dbus_header_get_byte_order (header),
                             NULL);
 
   return TRUE;
@@ -1463,28 +1496,19 @@ void
 _dbus_header_byteswap (DBusHeader *header,
                        int         new_order)
 {
-  if (header->byte_order == new_order)
+  char byte_order;
+
+  byte_order = _dbus_header_get_byte_order (header);
+
+  if (byte_order == new_order)
     return;
 
   _dbus_marshal_byteswap (&_dbus_header_signature_str,
-                          0, header->byte_order,
+                          0, byte_order,
                           new_order,
                           &header->data, 0);
 
-  header->byte_order = new_order;
+  _dbus_string_set_byte (&header->data, BYTE_ORDER_OFFSET, new_order);
 }
 
 /** @} */
-
-#ifdef DBUS_BUILD_TESTS
-#include "dbus-test.h"
-#include <stdio.h>
-
-dbus_bool_t
-_dbus_marshal_header_test (void)
-{
-
-  return TRUE;
-}
-
-#endif /* DBUS_BUILD_TESTS */