Add an accessor for the loader's corruption reason
[platform/upstream/dbus.git] / dbus / dbus-message.c
index 62b042e..272592e 100644 (file)
@@ -3785,6 +3785,21 @@ _dbus_message_loader_get_is_corrupted (DBusMessageLoader *loader)
 }
 
 /**
+ * Checks what kind of bad data confused the loader.
+ *
+ * @param loader the loader
+ * @returns why the loader is hosed, or DBUS_VALID if it isn't.
+ */
+DBusValidity
+_dbus_message_loader_get_corruption_reason (DBusMessageLoader *loader)
+{
+  _dbus_assert ((loader->corrupted && loader->corruption_reason != DBUS_VALID) ||
+                (!loader->corrupted && loader->corruption_reason == DBUS_VALID));
+
+  return loader->corruption_reason;
+}
+
+/**
  * Sets the maximum size message we allow.
  *
  * @param loader the loader
@@ -4000,6 +4015,7 @@ dbus_message_marshal (DBusMessage  *msg,
                       int          *len_p)
 {
   DBusString tmp;
+  dbus_bool_t was_locked;
 
   _dbus_return_val_if_fail (msg != NULL, FALSE);
   _dbus_return_val_if_fail (marshalled_data_p != NULL, FALSE);
@@ -4008,6 +4024,12 @@ dbus_message_marshal (DBusMessage  *msg,
   if (!_dbus_string_init (&tmp))
     return FALSE;
 
+  /* Ensure the message is locked, to ensure the length header is filled in. */
+  was_locked = msg->locked;
+
+  if (!was_locked)
+    dbus_message_lock (msg);
+
   if (!_dbus_string_copy (&(msg->header.data), 0, &tmp, 0))
     goto fail;
 
@@ -4022,10 +4044,18 @@ dbus_message_marshal (DBusMessage  *msg,
     goto fail;
 
   _dbus_string_free (&tmp);
+
+  if (!was_locked)
+    msg->locked = FALSE;
+
   return TRUE;
 
  fail:
   _dbus_string_free (&tmp);
+
+  if (!was_locked)
+    msg->locked = FALSE;
+
   return FALSE;
 }
 
@@ -4076,7 +4106,8 @@ dbus_message_demarshal (const char *str,
   return msg;
 
  fail_corrupt:
-  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted");
+  dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, "Message is corrupted (%s)",
+                  _dbus_validity_to_error_message (loader->corruption_reason));
   _dbus_message_loader_unref (loader);
   return NULL;