-/* -*- 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"
/** Static #DBusString containing the signature of a message header */
_DBUS_STRING_DEFINE_STATIC(_dbus_header_signature_str, DBUS_HEADER_SIGNATURE);
/** Static #DBusString containing the local interface */
-_DBUS_STRING_DEFINE_STATIC(_dbus_local_interface_str, DBUS_INTERFACE_ORG_FREEDESKTOP_LOCAL);
+_DBUS_STRING_DEFINE_STATIC(_dbus_local_interface_str, DBUS_INTERFACE_LOCAL);
/** Static #DBusString containing the local path */
-_DBUS_STRING_DEFINE_STATIC(_dbus_local_path_str, DBUS_PATH_ORG_FREEDESKTOP_LOCAL);
+_DBUS_STRING_DEFINE_STATIC(_dbus_local_path_str, DBUS_PATH_LOCAL);
/** Offset from start of _dbus_header_signature_str to the signature of the fields array */
#define FIELDS_ARRAY_SIGNATURE_OFFSET 6
typedef struct
{
- unsigned char code;
- unsigned char type;
+ unsigned char code; /**< the field code */
+ unsigned char type; /**< the value type */
} HeaderFieldType;
static const HeaderFieldType
{ 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 */
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);
}
/**
+ * 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
}
_dbus_type_reader_init (&reader,
- header->byte_order,
+ _dbus_header_get_byte_order (header),
&_dbus_header_signature_str,
FIELDS_ARRAY_SIGNATURE_OFFSET,
&header->data,
_dbus_marshal_set_uint32 (&header->data,
SERIAL_OFFSET,
serial,
- header->byte_order);
+ _dbus_header_get_byte_order (header));
}
/**
{
return _dbus_marshal_read_uint32 (&header->data,
SERIAL_OFFSET,
- header->byte_order,
+ _dbus_header_get_byte_order (header),
NULL);
}
* _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);
* @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;
}
*/
dbus_bool_t
_dbus_header_create (DBusHeader *header,
+ int byte_order,
int message_type,
const char *destination,
const char *path,
DBusTypeWriter writer;
DBusTypeWriter array;
- _dbus_assert ((interface && member) ||
+ _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));
_dbus_assert (_dbus_string_get_length (&header->data) == 0);
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;
}
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;
_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",
* 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
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;
}
_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,
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,
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,
_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;
_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 */