2003-03-31 Havoc Pennington <hp@redhat.com>
[platform/upstream/dbus.git] / dbus / dbus-message.c
index db1b94b..39ed394 100644 (file)
@@ -209,8 +209,7 @@ get_string_field (DBusMessage *message,
                                    offset,
                                    NULL);
 
-  _dbus_string_get_const_data (&message->header,
-                               &data);
+  data = _dbus_string_get_const_data (&message->header);
   
   return data + (offset + 4); 
 }
@@ -493,15 +492,21 @@ set_string_field (DBusMessage *message,
       DBusString v;
       int old_len;
       int new_len;
+      int len;
+      
+      clear_header_padding (message);
       
       old_len = _dbus_string_get_length (&message->header);
 
+      len = strlen (value);
+      
       _dbus_string_init_const_len (&v, value,
-                                   strlen (value) + 1); /* include nul */
+                                  len + 1); /* include nul */
       if (!_dbus_marshal_set_string (&message->header,
                                      message->byte_order,
-                                     offset, &v))
-        return FALSE;
+                                     offset, &v,
+                                    len))
+        goto failed;
       
       new_len = _dbus_string_get_length (&message->header);
 
@@ -509,33 +514,39 @@ set_string_field (DBusMessage *message,
                             offset,
                             new_len - old_len);
 
+      if (!append_header_padding (message))
+       goto failed;
+      
       return TRUE;
+
+    failed:
+      /* this must succeed because it was allocated on function entry and
+       * DBusString doesn't ever realloc smaller
+       */
+      if (!append_header_padding (message))
+       _dbus_assert_not_reached ("failed to reappend header padding");
+
+      return FALSE;
     }
 }
 
 /**
- * Sets the client serial of a message. 
+ * Sets the serial number of a message. 
  * This can only be done once on a message.
- *
- * @todo client_serial should be called simply
- * "serial"; it's in outgoing messages for both
- * the client and the server, it's only client-specific
- * in the message bus case. It's more like origin_serial
- * or something.
  * 
  * @param message the message
- * @param client_serial the client serial
+ * @param serial the serial
  */
 void
-_dbus_message_set_client_serial (DBusMessage  *message,
-                                dbus_int32_t  client_serial)
+_dbus_message_set_serial (DBusMessage  *message,
+                          dbus_int32_t  serial)
 {
   _dbus_assert (!message->locked);
-  _dbus_assert (_dbus_message_get_client_serial (message) < 0);
+  _dbus_assert (dbus_message_get_serial (message) < 0);
   
   set_int_field (message, FIELD_CLIENT_SERIAL,
-                 client_serial);
-  message->client_serial = client_serial;
+                 serial);
+  message->client_serial = serial;
 }
 
 /**
@@ -547,7 +558,7 @@ _dbus_message_set_client_serial (DBusMessage  *message,
  * @returns #FALSE if not enough memory
  */
 dbus_bool_t
-_dbus_message_set_reply_serial (DBusMessage  *message,
+dbus_message_set_reply_serial (DBusMessage  *message,
                                 dbus_int32_t  reply_serial)
 {
   _dbus_assert (!message->locked);
@@ -563,19 +574,15 @@ _dbus_message_set_reply_serial (DBusMessage  *message,
 }
 
 /**
- * Returns the client serial of a message or
- * -1 if none has been specified.
- *
- * @todo see note in _dbus_message_set_client_serial()
- * about how client_serial is a misnomer
- *
- * @todo this function should be public, after renaming it.
+ * Returns the serial of a message or -1 if none has been specified.
+ * The message's serial number is provided by the application sending
+ * the message and is used to identify replies to this message.
  *
  * @param message the message
  * @returns the client serial
  */
 dbus_int32_t
-_dbus_message_get_client_serial (DBusMessage *message)
+dbus_message_get_serial (DBusMessage *message)
 {
   return message->client_serial;
 }
@@ -588,7 +595,7 @@ _dbus_message_get_client_serial (DBusMessage *message)
  * @returns the reply serial
  */
 dbus_int32_t
-_dbus_message_get_reply_serial  (DBusMessage *message)
+dbus_message_get_reply_serial  (DBusMessage *message)
 {
   return message->reply_serial;
 }
@@ -620,8 +627,10 @@ _dbus_message_add_size_counter (DBusMessage *message,
     _dbus_string_get_length (&message->header) +
     _dbus_string_get_length (&message->body);
 
+#if 0
   _dbus_verbose ("message has size %ld\n",
                  message->size_counter_delta);
+#endif
   
   _dbus_counter_adjust (message->size_counter, message->size_counter_delta);
 }
@@ -749,13 +758,13 @@ dbus_message_new_empty_header (void)
       ++i;
     }
   
-  if (!_dbus_string_init (&message->header, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&message->header))
     {
       dbus_free (message);
       return NULL;
     }
   
-  if (!_dbus_string_init (&message->body, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&message->body))
     {
       _dbus_string_free (&message->header);
       dbus_free (message);
@@ -827,8 +836,8 @@ dbus_message_new_reply (DBusMessage *original_message)
   if (message == NULL)
     return NULL;
 
-  if (!_dbus_message_set_reply_serial (message,
-                                       _dbus_message_get_client_serial (original_message)))
+  if (!dbus_message_set_reply_serial (message,
+                                      dbus_message_get_serial (original_message)))
     {
       dbus_message_unref (message);
       return NULL;
@@ -863,8 +872,8 @@ dbus_message_new_error_reply (DBusMessage *original_message,
   if (message == NULL)
     return NULL;
 
-  if (!_dbus_message_set_reply_serial (message,
-                                       _dbus_message_get_client_serial (original_message)))
+  if (!dbus_message_set_reply_serial (message,
+                                      dbus_message_get_serial (original_message)))
     {
       dbus_message_unref (message);
       return NULL;
@@ -889,7 +898,7 @@ dbus_message_new_error_reply (DBusMessage *original_message,
  * @returns the new message.
  */
 DBusMessage *
-dbus_message_new_from_message (const DBusMessage *message)
+dbus_message_copy (const DBusMessage *message)
 {
   DBusMessage *retval;
   int i;
@@ -900,14 +909,18 @@ dbus_message_new_from_message (const DBusMessage *message)
   
   retval->refcount = 1;
   retval->byte_order = message->byte_order;
-
-  if (!_dbus_string_init (&retval->header, _DBUS_INT_MAX))
+  retval->client_serial = message->client_serial;
+  retval->reply_serial = message->reply_serial;
+  retval->header_padding = message->header_padding;
+  retval->locked = FALSE;
+  
+  if (!_dbus_string_init (&retval->header))
     {
       dbus_free (retval);
       return NULL;
     }
   
-  if (!_dbus_string_init (&retval->body, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&retval->body))
     {
       _dbus_string_free (&retval->header);
       dbus_free (retval);
@@ -1004,6 +1017,11 @@ dbus_message_get_name (DBusMessage *message)
 /**
  * Gets the destination service of a message.
  *
+ * @todo I think if we have set_sender/get_sender,
+ * this function might be better named set_destination/
+ * get_destination for clarity, as the sender
+ * is also a service name.
+ * 
  * @param message the message
  * @returns the message destination service (should not be freed)
  */
@@ -1162,7 +1180,16 @@ dbus_message_append_args_valist (DBusMessage *message,
              goto enomem;
          }
          break;
-         
+       case DBUS_TYPE_DICT:
+         {
+           DBusDict *dict;
+
+           dict = va_arg (var_args, DBusDict *);
+
+           if (!dbus_message_append_dict (message, dict))
+             goto enomem;
+           break;
+         }
        default:
          _dbus_warn ("Unknown field type %d\n", type);
        }
@@ -1465,9 +1492,9 @@ dbus_message_append_byte_array (DBusMessage         *message,
  * @returns #TRUE on success
  */
 dbus_bool_t
-dbus_message_append_string_array (DBusMessage *message,
-                                 const char **value,
-                                 int          len)
+dbus_message_append_string_array (DBusMessage  *message,
+                                 const char  **value,
+                                 int           len)
 {
   _dbus_assert (!message->locked);
 
@@ -1475,7 +1502,32 @@ dbus_message_append_string_array (DBusMessage *message,
     return FALSE;
 
   if (!_dbus_marshal_string_array (&message->body, message->byte_order,
-                                  value, len))
+                                  (const char **)value, len))
+    {
+      _dbus_string_shorten (&message->body, 1);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+/**
+ * Appends a dict to the message.
+ *
+ * @param message the message
+ * @param dict the dict
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_append_dict (DBusMessage *message,
+                         DBusDict    *dict)
+{
+  _dbus_assert (!message->locked);
+
+  if (!_dbus_string_append_byte (&message->body, DBUS_TYPE_DICT))
+    return FALSE;
+
+  if (!_dbus_marshal_dict (&message->body, message->byte_order, dict))
     {
       _dbus_string_shorten (&message->body, 1);
       return FALSE;
@@ -1491,20 +1543,24 @@ dbus_message_append_string_array (DBusMessage *message,
  * stored. The list is terminated with 0.
  *
  * @param message the message
+ * @param error error to be filled in on failure
  * @param first_arg_type the first argument type
  * @param ... location for first argument value, then list of type-location pairs
- * @returns result code
+ * @returns #FALSE if the error was set
  */
-DBusResultCode
+dbus_bool_t
 dbus_message_get_args (DBusMessage *message,
+                       DBusError   *error,
                       int          first_arg_type,
                       ...)
 {
-  DBusResultCode retval;
+  dbus_bool_t retval;
   va_list var_args;
 
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  
   va_start (var_args, first_arg_type);
-  retval = dbus_message_get_args_valist (message, first_arg_type, var_args);
+  retval = dbus_message_get_args_valist (message, error, first_arg_type, var_args);
   va_end (var_args);
 
   return retval;
@@ -1524,22 +1580,32 @@ dbus_message_get_args (DBusMessage *message,
  *
  * @see dbus_message_get_args
  * @param message the message
+ * @param error error to be filled in
  * @param first_arg_type type of the first argument
  * @param var_args return location for first argument, followed by list of type/location pairs
- * @returns result code
+ * @returns #FALSE if error was set
  */
-DBusResultCode
+dbus_bool_t
 dbus_message_get_args_valist (DBusMessage *message,
+                              DBusError   *error,
                              int          first_arg_type,
                              va_list      var_args)
 {
   int spec_type, msg_type, i;
   DBusMessageIter *iter;
+  dbus_bool_t retval;
 
+  _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+  
   iter = dbus_message_get_args_iter (message);
 
   if (iter == NULL)
-    return DBUS_RESULT_NO_MEMORY;
+    {
+      dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+      return FALSE;
+    }
+
+  retval = FALSE;
   
   spec_type = first_arg_type;
   i = 0;
@@ -1550,13 +1616,13 @@ dbus_message_get_args_valist (DBusMessage *message,
       
       if (msg_type != spec_type)
        {
-         _dbus_verbose ("Argument %d is specified to be of type \"%s\", but "
-                        "is actually of type \"%s\"\n", i,
-                        _dbus_type_to_string (spec_type),
-                        _dbus_type_to_string (msg_type));
-         dbus_message_iter_unref (iter);
+          dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+                          "Argument %d is specified to be of type \"%s\", but "
+                          "is actually of type \"%s\"\n", i,
+                          _dbus_type_to_string (spec_type),
+                          _dbus_type_to_string (msg_type));
 
-         return DBUS_RESULT_INVALID_ARGS;
+          goto out;
        }
 
       switch (spec_type)
@@ -1610,7 +1676,10 @@ dbus_message_get_args_valist (DBusMessage *message,
            *ptr = dbus_message_iter_get_string (iter);
 
            if (!*ptr)
-             return DBUS_RESULT_NO_MEMORY;
+              {
+                dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+                goto out;
+              }
            
            break;
          }
@@ -1624,8 +1693,10 @@ dbus_message_get_args_valist (DBusMessage *message,
            len = va_arg (var_args, int *);
 
            if (!dbus_message_iter_get_boolean_array (iter, ptr, len))
-             return DBUS_RESULT_NO_MEMORY;
-           
+              {
+                dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+                goto out;
+              }
            break;
          }
          
@@ -1638,7 +1709,10 @@ dbus_message_get_args_valist (DBusMessage *message,
            len = va_arg (var_args, int *);
 
            if (!dbus_message_iter_get_int32_array (iter, ptr, len))
-             return DBUS_RESULT_NO_MEMORY;
+              {
+                dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+                goto out;
+              }
            
            break;
          }
@@ -1652,7 +1726,10 @@ dbus_message_get_args_valist (DBusMessage *message,
            len = va_arg (var_args, int *);
 
            if (!dbus_message_iter_get_uint32_array (iter, ptr, len))
-             return DBUS_RESULT_NO_MEMORY;
+              {
+                dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+                goto out;
+              }
            
            break;
          }
@@ -1666,8 +1743,10 @@ dbus_message_get_args_valist (DBusMessage *message,
            len = va_arg (var_args, int *);
 
            if (!dbus_message_iter_get_double_array (iter, ptr, len))
-             return DBUS_RESULT_NO_MEMORY;
-           
+              {
+                dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+                goto out;
+              }
            break;
          }
          
@@ -1680,8 +1759,10 @@ dbus_message_get_args_valist (DBusMessage *message,
            len = va_arg (var_args, int *);
 
            if (!dbus_message_iter_get_byte_array (iter, ptr, len))
-             return DBUS_RESULT_NO_MEMORY;
-           
+              {
+                dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+                goto out;
+              }
            break;
          }
        case DBUS_TYPE_STRING_ARRAY:
@@ -1693,7 +1774,23 @@ dbus_message_get_args_valist (DBusMessage *message,
            len = va_arg (var_args, int *);
 
            if (!dbus_message_iter_get_string_array (iter, ptr, len))
-             return DBUS_RESULT_NO_MEMORY;
+              {
+                dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+                goto out;
+              }
+           break;
+         }
+       case DBUS_TYPE_DICT:
+         {
+           DBusDict **dict;
+
+           dict = va_arg (var_args, DBusDict **);
+
+           if (!dbus_message_iter_get_dict (iter, dict))
+              {
+                dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
+                goto out;
+              }
            break;
          }
        default:          
@@ -1702,17 +1799,20 @@ dbus_message_get_args_valist (DBusMessage *message,
       
       spec_type = va_arg (var_args, int);
       if (spec_type != 0 && !dbus_message_iter_next (iter))
-       {
-         _dbus_verbose ("More fields than exist in the message were specified or field is corrupt\n");
+        {
+          dbus_set_error (error, DBUS_ERROR_INVALID_ARGS,
+                          "Message has only %d arguments, but more were expected", i);
+          goto out;
+        }
 
-         dbus_message_iter_unref (iter);  
-         return DBUS_RESULT_INVALID_ARGS;
-       }
       i++;
     }
-
+  
+  retval = TRUE;
+  
+ out:
   dbus_message_iter_unref (iter);
-  return DBUS_RESULT_SUCCESS;
+  return retval;
 }
 
 /**
@@ -1848,9 +1948,9 @@ dbus_message_iter_get_arg_type (DBusMessageIter *iter)
   if (iter->pos >= _dbus_string_get_length (&iter->message->body))
     return DBUS_TYPE_INVALID;
 
-  _dbus_string_get_const_data_len (&iter->message->body, &data, iter->pos, 1);
+  data = _dbus_string_get_const_data_len (&iter->message->body, iter->pos, 1);
 
-  if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_STRING_ARRAY)
+  if (*data > DBUS_TYPE_INVALID && *data <= DBUS_TYPE_DICT)
     return *data;
 
   return DBUS_TYPE_INVALID;
@@ -1891,7 +1991,6 @@ dbus_message_iter_get_boolean (DBusMessageIter *iter)
   _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BOOLEAN);
 
   value = _dbus_string_get_byte (&iter->message->body, iter->pos + 1);
-  iter->pos += 2;
   
   return value;
 }
@@ -1967,10 +2066,8 @@ dbus_message_iter_get_boolean_array (DBusMessageIter   *iter,
 {
   _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BOOLEAN_ARRAY);
 
-  *value = _dbus_demarshal_byte_array (&iter->message->body, iter->message->byte_order,
-                                      iter->pos + 1, NULL, len);
-  
-  if (!*value)
+  if (!_dbus_demarshal_byte_array (&iter->message->body, iter->message->byte_order,
+                                  iter->pos + 1, NULL, value, len))
     return FALSE;
   else
     return TRUE;
@@ -1993,10 +2090,8 @@ dbus_message_iter_get_int32_array  (DBusMessageIter *iter,
 {
   _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_INT32_ARRAY);
 
-  *value = _dbus_demarshal_int32_array (&iter->message->body, iter->message->byte_order,
-                                       iter->pos + 1, NULL, len);
-  
-  if (!*value)
+  if (!_dbus_demarshal_int32_array (&iter->message->body, iter->message->byte_order,
+                                   iter->pos + 1, NULL, value, len))
     return FALSE;
   else
     return TRUE;
@@ -2019,10 +2114,8 @@ dbus_message_iter_get_uint32_array  (DBusMessageIter *iter,
 {
   _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_UINT32_ARRAY);
 
-  *value = _dbus_demarshal_uint32_array (&iter->message->body, iter->message->byte_order,
-                                        iter->pos + 1, NULL, len);
-  
-  if (!*value)
+  if (!_dbus_demarshal_uint32_array (&iter->message->body, iter->message->byte_order,
+                                    iter->pos + 1, NULL, value, len))
     return FALSE;
   else
     return TRUE;
@@ -2045,10 +2138,8 @@ dbus_message_iter_get_double_array  (DBusMessageIter *iter,
 {
   _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_DOUBLE_ARRAY);
 
-  *value = _dbus_demarshal_double_array (&iter->message->body, iter->message->byte_order,
-                                        iter->pos + 1, NULL, len);
-  
-  if (!*value)
+  if (!_dbus_demarshal_double_array (&iter->message->body, iter->message->byte_order,
+                                    iter->pos + 1, NULL, value, len))
     return FALSE;
   else
     return TRUE;
@@ -2062,7 +2153,7 @@ dbus_message_iter_get_double_array  (DBusMessageIter *iter,
  * @param iter the iterator
  * @param value return location for array values
  * @param len return location for length of byte array
- * @returns the byte array
+ * @returns #TRUE on success
  */
 dbus_bool_t
 dbus_message_iter_get_byte_array (DBusMessageIter  *iter,
@@ -2070,11 +2161,9 @@ dbus_message_iter_get_byte_array (DBusMessageIter  *iter,
                                   int              *len)
 {
   _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_BYTE_ARRAY);
-  
-  *value = _dbus_demarshal_byte_array (&iter->message->body, iter->message->byte_order,
-                                      iter->pos + 1, NULL, len);
 
-  if (!*value)
+  if (!_dbus_demarshal_byte_array (&iter->message->body, iter->message->byte_order,
+                                  iter->pos + 1, NULL, value, len))
     return FALSE;
   else
     return TRUE;
@@ -2093,7 +2182,7 @@ dbus_message_iter_get_byte_array (DBusMessageIter  *iter,
  * @param iter the iterator
  * @param value return location for string values
  * @param len return location for length of byte array
- * @returns the byte array
+ * @returns #TRUE on success
  */
 dbus_bool_t
 dbus_message_iter_get_string_array (DBusMessageIter *iter,
@@ -2102,10 +2191,30 @@ dbus_message_iter_get_string_array (DBusMessageIter *iter,
 {
   _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_STRING_ARRAY);
 
-  *value = _dbus_demarshal_string_array (&iter->message->body, iter->message->byte_order,
-                                        iter->pos + 1, NULL, len);
+  if (!_dbus_demarshal_string_array (&iter->message->body, iter->message->byte_order,
+                                    iter->pos + 1, NULL, value, len))
+    return FALSE;
+  else
+    return TRUE;
+}
 
-  if (!*value)
+/**
+ * Returns the dict that the iterator may point to.
+ * Note that you need to check that the iterator points
+ * to a dict prior to using this function.
+ *
+ * @param iter the iterator
+ * @param dict return location for dict
+ * @returns #TRUE on success
+ */
+dbus_bool_t
+dbus_message_iter_get_dict (DBusMessageIter *iter,
+                           DBusDict       **dict)
+{
+  _dbus_assert (dbus_message_iter_get_arg_type (iter) == DBUS_TYPE_DICT);
+
+  if (!_dbus_demarshal_dict (&iter->message->body, iter->message->byte_order,
+                            iter->pos + 1, NULL, dict))
     return FALSE;
   else
     return TRUE;
@@ -2152,7 +2261,7 @@ dbus_message_set_is_error (DBusMessage *message,
   
   _dbus_assert (!message->locked);
   
-  _dbus_string_get_data_len (&message->header, &header, 1, 1);
+  header = _dbus_string_get_data_len (&message->header, 1, 1);
   
   if (is_error_reply)
     *header |= DBUS_HEADER_FLAG_ERROR;
@@ -2172,7 +2281,7 @@ dbus_message_get_is_error (DBusMessage *message)
 {
   const char *header;
 
-  _dbus_string_get_const_data_len (&message->header, &header, 1, 1);
+  header = _dbus_string_get_const_data_len (&message->header, 1, 1);
 
   return (*header & DBUS_HEADER_FLAG_ERROR) != 0;
 }
@@ -2216,6 +2325,62 @@ dbus_message_name_is (DBusMessage *message,
     return FALSE;
 }
 
+/**
+ * Checks whether the message was sent to the given service.  If the
+ * message has no service specified or has a different name, returns
+ * #FALSE.
+ *
+ * @param message the message
+ * @param service the service to check (must not be #NULL)
+ * 
+ * @returns #TRUE if the message has the given destination service
+ */
+dbus_bool_t
+dbus_message_service_is (DBusMessage  *message,
+                         const char   *service)
+{
+  const char *s;
+
+  _dbus_assert (service != NULL);
+  
+  s = dbus_message_get_service (message);
+
+  if (s && strcmp (s, service) == 0)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+/**
+ * Checks whether the message has the given service as its sender.  If
+ * the message has no sender specified or has a different sender,
+ * returns #FALSE. Note that if a peer application owns multiple
+ * services, its messages will have only one of those services as the
+ * sender (usually the base service). So you can't use this
+ * function to prove the sender didn't own service Foo, you can
+ * only use it to prove that it did.
+ *
+ * @param message the message
+ * @param service the service to check (must not be #NULL)
+ * 
+ * @returns #TRUE if the message has the given origin service
+ */
+dbus_bool_t
+dbus_message_sender_is (DBusMessage  *message,
+                        const char   *service)
+{
+  const char *s;
+
+  _dbus_assert (service != NULL);
+  
+  s = dbus_message_get_sender (message);
+
+  if (s && strcmp (s, service) == 0)
+    return TRUE;
+  else
+    return FALSE;
+}
+
 /** @} */
 
 /**
@@ -2233,6 +2398,10 @@ dbus_message_name_is (DBusMessage *message,
  * DBusTransport implementation. The DBusTransport then hands off
  * the loaded messages to a DBusConnection, making the messages
  * visible to the application.
+ *
+ * @todo write tests for break-loader that a) randomly delete header
+ * fields and b) set string fields to zero-length and other funky
+ * values.
  * 
  */
 
@@ -2299,7 +2468,7 @@ _dbus_message_loader_new (void)
    */
   loader->max_message_size = _DBUS_ONE_MEGABYTE * 32;
   
-  if (!_dbus_string_init (&loader->data, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&loader->data))
     {
       dbus_free (loader);
       return NULL;
@@ -2442,7 +2611,7 @@ decode_header_data (const DBusString   *data,
       if ((pos + 4) > header_len)
         return FALSE;      
       
-      _dbus_string_get_const_data_len (data, &field, pos, 4);
+      field =_dbus_string_get_const_data_len (data, pos, 4);
       pos += 4;
 
       _dbus_assert (_DBUS_ALIGN_ADDRESS (field, 4) == field);
@@ -2461,13 +2630,15 @@ decode_header_data (const DBusString   *data,
             }
           
           fields[FIELD_SERVICE].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
+#if 0
           _dbus_verbose ("Found service name at offset %d\n",
                          fields[FIELD_SERVICE].offset);
+#endif
           break;
 
         case DBUS_HEADER_FIELD_NAME_AS_UINT32:
           if (fields[FIELD_NAME].offset >= 0)
-            {
+            {              
               _dbus_verbose ("%s field provided twice\n",
                              DBUS_HEADER_FIELD_NAME);
               return FALSE;
@@ -2475,8 +2646,10 @@ decode_header_data (const DBusString   *data,
           
           fields[FIELD_NAME].offset = _DBUS_ALIGN_VALUE (pos + 1, 4);
 
+#if 0
           _dbus_verbose ("Found message name at offset %d\n",
                          fields[FIELD_NAME].offset);
+#endif
           break;
        case DBUS_HEADER_FIELD_SENDER_AS_UINT32:
           if (fields[FIELD_SENDER].offset >= 0)
@@ -2539,6 +2712,13 @@ decode_header_data (const DBusString   *data,
         }
     }
 
+ if (fields[FIELD_NAME].offset < 0)
+   {
+     _dbus_verbose ("No %s field provided\n",
+                    DBUS_HEADER_FIELD_NAME);
+     return FALSE;
+   }
+  
   if (message_padding)
     *message_padding = header_len - pos;  
   
@@ -2551,12 +2731,6 @@ decode_header_data (const DBusString   *data,
  * in. This function must always be called, even if no bytes were
  * successfully read.
  *
- * @todo if we run out of memory in here, we offer no way for calling
- * code to handle it, i.e. they can't re-run the message parsing
- * attempt. Perhaps much of this code could be moved to pop_message()?
- * But then that may need to distinguish NULL return for no messages
- * from NULL return for errors.
- *
  * @param loader the loader.
  * @param buffer the buffer.
  * @param bytes_read number of bytes that were read into the buffer.
@@ -2570,9 +2744,19 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
   _dbus_assert (buffer == &loader->data);
 
   loader->buffer_outstanding = FALSE;
+}
 
+/**
+ * Converts buffered data into messages.
+ *
+ * @param loader the loader.
+ * @returns #TRUE if we had enough memory to finish.
+ */
+dbus_bool_t
+_dbus_message_loader_queue_messages (DBusMessageLoader *loader)
+{
   if (loader->corrupted)
-    return;
+    return TRUE;
 
   while (_dbus_string_get_length (&loader->data) >= 16)
     {
@@ -2581,7 +2765,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
       int byte_order, header_len, body_len, header_padding;
       dbus_uint32_t header_len_unsigned, body_len_unsigned;
       
-      _dbus_string_get_const_data_len (&loader->data, &header_data, 0, 16);
+      header_data = _dbus_string_get_const_data_len (&loader->data, 0, 16);
 
       _dbus_assert (_DBUS_ALIGN_ADDRESS (header_data, 4) == header_data);
 
@@ -2590,7 +2774,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
           _dbus_verbose ("Message has protocol version %d ours is %d\n",
                          (int) header_data[2], DBUS_MAJOR_PROTOCOL_VERSION);
           loader->corrupted = TRUE;
-          return;
+          return TRUE;
         }
       
       byte_order = header_data[0];
@@ -2601,7 +2785,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
           _dbus_verbose ("Message with bad byte order '%c' received\n",
                          byte_order);
          loader->corrupted = TRUE;
-         return;
+         return TRUE;
        }
 
       header_len_unsigned = _dbus_unpack_uint32 (byte_order, header_data + 4);
@@ -2612,7 +2796,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
           _dbus_verbose ("Message had broken too-small header length %u\n",
                          header_len_unsigned);
           loader->corrupted = TRUE;
-          return;
+          return TRUE;
         }
 
       if (header_len_unsigned > (unsigned) MAX_SANE_MESSAGE_SIZE ||
@@ -2622,7 +2806,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
                          header_len_unsigned,
                          body_len_unsigned);
           loader->corrupted = TRUE;
-          return;
+          return TRUE;
         }
 
       /* Now that we know the values are in signed range, get
@@ -2630,21 +2814,22 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
        */
       header_len = header_len_unsigned;
       body_len = body_len_unsigned;
-      
+
       if (_DBUS_ALIGN_VALUE (header_len, 8) != header_len_unsigned)
         {
+         
           _dbus_verbose ("header length %d is not aligned to 8 bytes\n",
                          header_len);
           loader->corrupted = TRUE;
-          return;
+          return TRUE;
         }
       
       if (header_len + body_len > loader->max_message_size)
        {
-          _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %d\n",
+          _dbus_verbose ("Message claimed length header = %d body = %d exceeds max message length %ld\n",
                          header_len, body_len, loader->max_message_size);
          loader->corrupted = TRUE;
-         return;
+         return TRUE;
        }
 
       if (_dbus_string_get_length (&loader->data) >= (header_len + body_len))
@@ -2654,14 +2839,14 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
           int next_arg;          
 
 #if 0
-         _dbus_verbose_bytes_of_string (&loader->data, 0, header_len);
-#endif
+         _dbus_verbose_bytes_of_string (&loader->data, 0, header_len + body_len);
+#endif   
          if (!decode_header_data (&loader->data, header_len, byte_order,
                                    fields, &header_padding))
            {
               _dbus_verbose ("Header was invalid\n");
              loader->corrupted = TRUE;
-             return;
+             return TRUE;
            }
           
           next_arg = header_len;
@@ -2675,7 +2860,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
                                                &next_arg))
                 {
                   loader->corrupted = TRUE;
-                  return;
+                  return TRUE;
                 }
 
               _dbus_assert (next_arg > prev);
@@ -2687,12 +2872,12 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
                              next_arg, header_len, body_len,
                              header_len + body_len);
               loader->corrupted = TRUE;
-              return;
+              return TRUE;
             }
 
          message = dbus_message_new_empty_header ();
          if (message == NULL)
-            break; /* ugh, postpone this I guess. */
+            return FALSE;
 
           message->byte_order = byte_order;
           message->header_padding = header_padding;
@@ -2708,7 +2893,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
          if (!_dbus_list_append (&loader->messages, message))
             {
               dbus_message_unref (message);
-              break;
+              return FALSE;
             }
 
           _dbus_assert (_dbus_string_get_length (&message->header) == 0);
@@ -2721,7 +2906,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
             {
               _dbus_list_remove_last (&loader->messages, message);
               dbus_message_unref (message);
-              break;
+              return FALSE;
             }
           
          if (!_dbus_string_move_len (&loader->data, 0, body_len, &message->body, 0))
@@ -2735,7 +2920,7 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
 
               _dbus_list_remove_last (&loader->messages, message);
               dbus_message_unref (message);
-              break;
+              return FALSE;
             }
 
           _dbus_assert (_dbus_string_get_length (&message->header) == header_len);
@@ -2750,14 +2935,32 @@ _dbus_message_loader_return_buffer (DBusMessageLoader  *loader,
          _dbus_verbose ("Loaded message %p\n", message);
        }
       else
-       break;
+        return TRUE;
     }
+
+  return TRUE;
+}
+
+/**
+ * Peeks at first loaded message, returns #NULL if no messages have
+ * been queued.
+ *
+ * @param loader the loader.
+ * @returns the next message, or #NULL if none.
+ */
+DBusMessage*
+_dbus_message_loader_peek_message (DBusMessageLoader *loader)
+{
+  if (loader->messages)
+    return loader->messages->data;
+  else
+    return NULL;
 }
 
 /**
  * Pops a loaded message (passing ownership of the message
  * to the caller). Returns #NULL if no messages have been
- * loaded.
+ * queued.
  *
  * @param loader the loader.
  * @returns the next message, or #NULL if none.
@@ -2768,6 +2971,19 @@ _dbus_message_loader_pop_message (DBusMessageLoader *loader)
   return _dbus_list_pop_first (&loader->messages);
 }
 
+/**
+ * Pops a loaded message inside a list link (passing ownership of the
+ * message and link to the caller). Returns #NULL if no messages have
+ * been loaded.
+ *
+ * @param loader the loader.
+ * @returns the next message link, or #NULL if none.
+ */
+DBusList*
+_dbus_message_loader_pop_message_link (DBusMessageLoader *loader)
+{
+  return _dbus_list_pop_first_link (&loader->messages);
+}
 
 /**
  * Checks whether the loader is confused due to bad data.
@@ -2884,13 +3100,13 @@ check_message_handling (DBusMessage *message)
   retval = FALSE;
   iter = NULL;
   
-  client_serial = _dbus_message_get_client_serial (message);
+  client_serial = dbus_message_get_serial (message);
 
-  /* can't use set_client_serial due to the assertions at the start of it */
+  /* can't use set_serial due to the assertions at the start of it */
   set_int_field (message, FIELD_CLIENT_SERIAL,
                  client_serial);
-
-  if (client_serial != _dbus_message_get_client_serial (message))
+  
+  if (client_serial != dbus_message_get_serial (message))
     {
       _dbus_warn ("get/set cycle for client_serial did not succeed\n");
       goto failed;
@@ -2899,7 +3115,7 @@ check_message_handling (DBusMessage *message)
   /* If we implement message_set_arg (message, n, value)
    * then we would want to test it here
    */
-  
+
   iter = dbus_message_get_args_iter (message);
   while ((type = dbus_message_iter_get_arg_type (iter)) != DBUS_TYPE_INVALID)
     {
@@ -2923,6 +3139,17 @@ check_message_handling (DBusMessage *message)
             dbus_free (str);
           }
           break;
+        case DBUS_TYPE_BOOLEAN_ARRAY:
+          {
+           unsigned char *values;
+           int len;
+           
+            if (!dbus_message_iter_get_boolean_array (iter, &values, &len))
+             return FALSE;
+
+           dbus_free (values);
+          }
+          break;
         case DBUS_TYPE_INT32_ARRAY:
           {
            dbus_int32_t *values;
@@ -2967,7 +3194,17 @@ check_message_handling (DBusMessage *message)
            dbus_free_string_array (values);
           }
           break;
-         
+
+       case DBUS_TYPE_DICT:
+         {
+           DBusDict *dict;
+
+           if (!dbus_message_iter_get_dict (iter, &dict))
+             return FALSE;
+           dbus_dict_unref (dict);
+         }
+         break;
+
        default:
          break;
         }
@@ -2993,6 +3230,9 @@ check_have_valid_message (DBusMessageLoader *loader)
 
   message = NULL;
   retval = FALSE;
+
+  if (!_dbus_message_loader_queue_messages (loader))
+    _dbus_assert_not_reached ("no memory to queue messages");
   
   if (_dbus_message_loader_get_is_corrupted (loader))
     {
@@ -3025,6 +3265,7 @@ check_have_valid_message (DBusMessageLoader *loader)
  failed:
   if (message)
     dbus_message_unref (message);
+
   return retval;
 }
 
@@ -3034,6 +3275,9 @@ check_invalid_message (DBusMessageLoader *loader)
   dbus_bool_t retval;
 
   retval = FALSE;
+
+  if (!_dbus_message_loader_queue_messages (loader))
+    _dbus_assert_not_reached ("no memory to queue messages");
   
   if (!_dbus_message_loader_get_is_corrupted (loader))
     {
@@ -3055,6 +3299,9 @@ check_incomplete_message (DBusMessageLoader *loader)
 
   message = NULL;
   retval = FALSE;
+
+  if (!_dbus_message_loader_queue_messages (loader))
+    _dbus_assert_not_reached ("no memory to queue messages");
   
   if (_dbus_message_loader_get_is_corrupted (loader))
     {
@@ -3081,6 +3328,9 @@ static dbus_bool_t
 check_loader_results (DBusMessageLoader      *loader,
                       DBusMessageValidity     validity)
 {
+  if (!_dbus_message_loader_queue_messages (loader))
+    _dbus_assert_not_reached ("no memory to queue messages");
+  
   switch (validity)
     {
     case _DBUS_MESSAGE_VALID:
@@ -3117,14 +3367,15 @@ dbus_internal_do_not_use_load_message_file (const DBusString    *filename,
 
   if (is_raw)
     {
-      DBusResultCode result;
+      DBusError error;
 
-      result = _dbus_file_get_contents (data, filename);
-      if (result != DBUS_RESULT_SUCCESS)
+      dbus_error_init (&error);
+      if (!_dbus_file_get_contents (data, filename, &error))
         {
-          const char *s;      
-          _dbus_string_get_const_data (filename, &s);
-          _dbus_warn ("Could not load message file %s\n", s);
+          _dbus_warn ("Could not load message file %s: %s\n",
+                      _dbus_string_get_const_data (filename),
+                      error.message);
+          dbus_error_free (&error);
           goto failed;
         }
     }
@@ -3132,9 +3383,8 @@ dbus_internal_do_not_use_load_message_file (const DBusString    *filename,
     {
       if (!_dbus_message_data_load (data, filename))
         {
-          const char *s;      
-          _dbus_string_get_const_data (filename, &s);
-          _dbus_warn ("Could not load message file %s\n", s);
+          _dbus_warn ("Could not load message file %s\n",
+                      _dbus_string_get_const_data (filename));
           goto failed;
         }
     }
@@ -3165,7 +3415,7 @@ dbus_internal_do_not_use_try_message_file (const DBusString    *filename,
 
   retval = FALSE;
   
-  if (!_dbus_string_init (&data, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&data))
     _dbus_assert_not_reached ("could not allocate string\n");
 
   if (!dbus_internal_do_not_use_load_message_file (filename, is_raw,
@@ -3178,15 +3428,12 @@ dbus_internal_do_not_use_try_message_file (const DBusString    *filename,
 
   if (!retval)
     {
-      const char *s;
-
       if (_dbus_string_get_length (&data) > 0)
         _dbus_verbose_bytes_of_string (&data, 0,
                                        _dbus_string_get_length (&data));
       
-      _dbus_string_get_const_data (filename, &s);
       _dbus_warn ("Failed message loader test on %s\n",
-                  s);
+                  _dbus_string_get_const_data (filename));
     }
   
   _dbus_string_free (&data);
@@ -3299,12 +3546,12 @@ process_test_subdir (const DBusString          *test_base_dir,
   DBusString filename;
   DBusDirIter *dir;
   dbus_bool_t retval;
-  DBusResultCode result;
+  DBusError error;
 
   retval = FALSE;
   dir = NULL;
   
-  if (!_dbus_string_init (&test_directory, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&test_directory))
     _dbus_assert_not_reached ("didn't allocate test_directory\n");
 
   _dbus_string_init_const (&filename, subdir);
@@ -3317,29 +3564,29 @@ process_test_subdir (const DBusString          *test_base_dir,
     _dbus_assert_not_reached ("couldn't allocate full path");
 
   _dbus_string_free (&filename);
-  if (!_dbus_string_init (&filename, _DBUS_INT_MAX))
+  if (!_dbus_string_init (&filename))
     _dbus_assert_not_reached ("didn't allocate filename string\n");
-  
-  dir = _dbus_directory_open (&test_directory, &result);
+
+  dbus_error_init (&error);
+  dir = _dbus_directory_open (&test_directory, &error);
   if (dir == NULL)
     {
-      const char *s;
-      _dbus_string_get_const_data (&test_directory, &s);
-      _dbus_warn ("Could not open %s: %s\n", s,
-                  dbus_result_to_string (result));
+      _dbus_warn ("Could not open %s: %s\n",
+                  _dbus_string_get_const_data (&test_directory),
+                  error.message);
+      dbus_error_free (&error);
       goto failed;
     }
 
   printf ("Testing:\n");
   
-  result = DBUS_RESULT_SUCCESS;
  next:
-  while (_dbus_directory_get_next_file (dir, &filename, &result))
+  while (_dbus_directory_get_next_file (dir, &filename, &error))
     {
       DBusString full_path;
       dbus_bool_t is_raw;
       
-      if (!_dbus_string_init (&full_path, _DBUS_INT_MAX))
+      if (!_dbus_string_init (&full_path))
         _dbus_assert_not_reached ("couldn't init string");
 
       if (!_dbus_string_copy (&test_directory, 0, &full_path, 0))
@@ -3354,19 +3601,14 @@ process_test_subdir (const DBusString          *test_base_dir,
         is_raw = TRUE;
       else
         {
-          const char *filename_c;
-          _dbus_string_get_const_data (&filename, &filename_c);
           _dbus_verbose ("Skipping non-.message file %s\n",
-                         filename_c);
+                         _dbus_string_get_const_data (&filename));
          _dbus_string_free (&full_path);
           goto next;
         }
 
-      {
-        const char *s;
-        _dbus_string_get_const_data (&filename, &s);
-        printf ("    %s\n", s);
-      }
+      printf ("    %s\n",
+              _dbus_string_get_const_data (&filename));
       
       _dbus_verbose (" expecting %s\n",
                      validity == _DBUS_MESSAGE_VALID ? "valid" :
@@ -3382,12 +3624,12 @@ process_test_subdir (const DBusString          *test_base_dir,
         _dbus_string_free (&full_path);
     }
 
-  if (result != DBUS_RESULT_SUCCESS)
+  if (dbus_error_is_set (&error))
     {
-      const char *s;
-      _dbus_string_get_const_data (&test_directory, &s);
       _dbus_warn ("Could not get next file in %s: %s\n",
-                  s, dbus_result_to_string (result));
+                  _dbus_string_get_const_data (&test_directory),
+                  error.message);
+      dbus_error_free (&error);
       goto failed;
     }
     
@@ -3445,6 +3687,37 @@ dbus_internal_do_not_use_foreach_message_file (const char                *test_d
   return retval;
 }
 
+static void
+verify_test_message (DBusMessage *message)
+{
+  dbus_int32_t our_int;
+  char *our_str;
+  double our_double;
+  dbus_bool_t our_bool;
+  
+  if (!dbus_message_get_args (message, NULL,
+                              DBUS_TYPE_INT32, &our_int,
+                              DBUS_TYPE_STRING, &our_str,
+                              DBUS_TYPE_DOUBLE, &our_double,
+                              DBUS_TYPE_BOOLEAN, &our_bool,
+                              0))
+    _dbus_assert_not_reached ("Could not get arguments");
+
+  if (our_int != -0x12345678)
+    _dbus_assert_not_reached ("integers differ!");
+
+  if (our_double != 3.14159)
+    _dbus_assert_not_reached ("doubles differ!");
+
+  if (strcmp (our_str, "Test string") != 0)
+    _dbus_assert_not_reached ("strings differ!");
+
+  if (!our_bool)
+    _dbus_assert_not_reached ("booleans differ");
+  
+  dbus_free (our_str);
+}
+
 /**
  * @ingroup DBusMessageInternals
  * Unit test for DBusMessage.
@@ -3458,14 +3731,13 @@ _dbus_message_test (const char *test_data_dir)
   DBusMessageLoader *loader;
   int i;
   const char *data;
-  dbus_int32_t our_int;
-  char *our_str;
-  double our_double;
-  dbus_bool_t our_bool;
+  DBusMessage *copy;
+  const char *name1;
+  const char *name2;
   
   /* Test the vararg functions */
   message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
-  _dbus_message_set_client_serial (message, 1);
+  _dbus_message_set_serial (message, 1);
   dbus_message_append_args (message,
                            DBUS_TYPE_INT32, -0x12345678,
                            DBUS_TYPE_STRING, "Test string",
@@ -3476,33 +3748,34 @@ _dbus_message_test (const char *test_data_dir)
                                  _dbus_string_get_length (&message->header));
   _dbus_verbose_bytes_of_string (&message->body, 0,
                                  _dbus_string_get_length (&message->body));
+
+  verify_test_message (message);
+
+  copy = dbus_message_copy (message);
   
-  if (dbus_message_get_args (message,
-                            DBUS_TYPE_INT32, &our_int,
-                            DBUS_TYPE_STRING, &our_str,
-                            DBUS_TYPE_DOUBLE, &our_double,
-                            DBUS_TYPE_BOOLEAN, &our_bool,
-                            0) != DBUS_RESULT_SUCCESS)
-    _dbus_assert_not_reached ("Could not get arguments");
+  _dbus_assert (message->client_serial == copy->client_serial);
+  _dbus_assert (message->reply_serial == copy->reply_serial);
+  _dbus_assert (message->header_padding == copy->header_padding);
+  
+  _dbus_assert (_dbus_string_get_length (&message->header) ==
+                _dbus_string_get_length (&copy->header));
 
-  if (our_int != -0x12345678)
-    _dbus_assert_not_reached ("integers differ!");
+  _dbus_assert (_dbus_string_get_length (&message->body) ==
+                _dbus_string_get_length (&copy->body));
 
-  if (our_double != 3.14159)
-    _dbus_assert_not_reached ("doubles differ!");
+  verify_test_message (copy);
 
-  if (strcmp (our_str, "Test string") != 0)
-    _dbus_assert_not_reached ("strings differ!");
+  name1 = dbus_message_get_name (message);
+  name2 = dbus_message_get_name (copy);
 
-  if (!our_bool)
-    _dbus_assert_not_reached ("booleans differ");
+  _dbus_assert (strcmp (name1, name2) == 0);
   
-  dbus_free (our_str);
   dbus_message_unref (message);
+  dbus_message_unref (copy);
   
   message = dbus_message_new ("org.freedesktop.DBus.Test", "testMessage");
-  _dbus_message_set_client_serial (message, 1);
-  _dbus_message_set_reply_serial (message, 0x12345678);
+  _dbus_message_set_serial (message, 1);
+  dbus_message_set_reply_serial (message, 0x12345678);
 
   dbus_message_append_string (message, "Test string");
   dbus_message_append_int32 (message, -0x12345678);
@@ -3516,7 +3789,7 @@ _dbus_message_test (const char *test_data_dir)
   loader = _dbus_message_loader_new ();
 
   /* Write the header data one byte at a time */
-  _dbus_string_get_const_data (&message->header, &data);
+  data = _dbus_string_get_const_data (&message->header);
   for (i = 0; i < _dbus_string_get_length (&message->header); i++)
     {
       DBusString *buffer;
@@ -3527,7 +3800,7 @@ _dbus_message_test (const char *test_data_dir)
     }
 
   /* Write the body data one byte at a time */
-  _dbus_string_get_const_data (&message->body, &data);
+  data = _dbus_string_get_const_data (&message->body);
   for (i = 0; i < _dbus_string_get_length (&message->body); i++)
     {
       DBusString *buffer;
@@ -3540,6 +3813,9 @@ _dbus_message_test (const char *test_data_dir)
   dbus_message_unref (message);
 
   /* Now pop back the message */
+  if (!_dbus_message_loader_queue_messages (loader))
+    _dbus_assert_not_reached ("no memory to queue messages");
+  
   if (_dbus_message_loader_get_is_corrupted (loader))
     _dbus_assert_not_reached ("message loader corrupted");
   
@@ -3547,7 +3823,7 @@ _dbus_message_test (const char *test_data_dir)
   if (!message)
     _dbus_assert_not_reached ("received a NULL message");
 
-  if (_dbus_message_get_reply_serial (message) != 0x12345678)
+  if (dbus_message_get_reply_serial (message) != 0x12345678)
     _dbus_assert_not_reached ("reply serial fields differ");
   
   message_iter_test (message);