dbus-marshal-validate: Check brackets in signature nest correctly
[platform/upstream/dbus.git] / dbus / dbus-connection.c
index e6c29fd..e010579 100644 (file)
 #include "dbus-bus.h"
 #include "dbus-marshal-basic.h"
 
-#ifdef DBUS_ENABLE_SMACK
-#include <sys/smack.h>
-#include <stdlib.h>
-#endif
-
 #ifdef DBUS_DISABLE_CHECKS
 #define TOOK_LOCK_CHECK(connection)
 #define RELEASING_LOCK_CHECK(connection)
@@ -309,9 +304,6 @@ struct DBusConnection
   DBusObjectTree *objects; /**< Object path handlers registered with this connection */
 
   char *server_guid; /**< GUID of server if we are in shared_connections, #NULL if server GUID is unknown or connection is private */
-#ifdef DBUS_ENABLE_SMACK
-  char *peer_smack_label; /** Smack label of the peer at the time when the connection was established. Allocated with malloc(), NULL if unknown. */
-#endif
 
   /* These two MUST be bools and not bitfields, because they are protected by a separate lock
    * from connection->mutex and all bitfields in a word have to be read/written together.
@@ -594,12 +586,13 @@ _dbus_connection_queue_synthesized_message_link (DBusConnection *connection,
   msg = (DBusMessage *)link->data;
 
   rmsg = msg;
-  _dbus_transport_assure_protocol_version (connection->transport, &rmsg);
-
-  if (rmsg != msg) {
-    _dbus_list_free_link(link);
-    link = _dbus_list_alloc_link (rmsg);
-  }
+  if (_dbus_transport_assure_protocol_version (connection->transport, &rmsg))
+    {
+      /* If the message is converted, then we don't need the old format anymore */
+      _dbus_list_free_link(link);
+      link = _dbus_list_alloc_link (rmsg);
+      dbus_message_unref (msg);
+    }
 
   _dbus_list_append_link (&connection->incoming_messages, link);
 
@@ -1339,19 +1332,6 @@ _dbus_connection_new_for_transport (DBusTransport *transport)
   if (connection == NULL)
     goto error;
 
-#ifdef DBUS_ENABLE_SMACK
-  /* If we cannot get the Smack label, proceed without. */
-  {
-    DBusSocket sock_fd;
-    if (_dbus_transport_get_socket_fd(transport, &sock_fd)) {
-      char *label;
-      if (smack_new_label_from_socket(_dbus_socket_get_int (sock_fd), &label) >= 0) {
-        connection->peer_smack_label = label;
-      }
-    }
-  }
-#endif
-
   _dbus_rmutex_new_at_location (&connection->mutex);
   if (connection->mutex == NULL)
     goto error;
@@ -2085,7 +2065,13 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *con
   dbus_message_lock (message);
 
   /* This converts message if neccessary */
-  _dbus_transport_assure_protocol_version (connection->transport, &message);
+  if (!_dbus_transport_assure_protocol_version (connection->transport, &message))
+    {
+      /* Only non-converted messages must be refed.
+       * Converted messages are local anyway.
+       */
+      dbus_message_ref (message);
+    }
 
   preallocated->queue_link->data = message;
   _dbus_list_prepend_link (&connection->outgoing_messages,
@@ -2099,8 +2085,6 @@ _dbus_connection_send_preallocated_unlocked_no_update (DBusConnection       *con
   dbus_free (preallocated);
   preallocated = NULL;
   
-  dbus_message_ref (message);
-  
   connection->n_outgoing += 1;
 
   _dbus_verbose ("Message %p (%s %s %s %s '%s') for %s added to outgoing queue %p, %d pending to send\n",
@@ -2350,10 +2334,11 @@ complete_pending_call_and_unlock (DBusConnection  *connection,
 {
   _dbus_pending_call_set_reply_unlocked (pending, message);
   _dbus_pending_call_ref_unlocked (pending); /* in case there's no app with a ref held */
+  _dbus_pending_call_start_completion_unlocked(pending);
   _dbus_connection_detach_pending_call_and_unlock (connection, pending);
+
   /* Must be called unlocked since it invokes app callback */
-  _dbus_pending_call_complete (pending);
+  _dbus_pending_call_finish_completion (pending);
   dbus_pending_call_unref (pending);
 }
 
@@ -2501,6 +2486,8 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
 
       /* on OOM error_msg is set to NULL */
       complete_pending_call_and_unlock (connection, pending, error_msg);
+      if (error_msg != NULL)
+        dbus_message_unref (error_msg);
       dbus_pending_call_unref (pending);
       return;
     }
@@ -2550,7 +2537,7 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
         {          
           /* block again, we don't have the reply buffered yet. */
           _dbus_connection_do_iteration_unlocked (connection,
-                                                  NULL,
+                                                  pending,
                                                   DBUS_ITERATION_DO_READING |
                                                   DBUS_ITERATION_BLOCK,
                                                   timeout_milliseconds - elapsed_milliseconds);
@@ -2783,8 +2770,6 @@ _dbus_connection_last_unref (DBusConnection *connection)
   _dbus_hash_table_unref (connection->pending_replies);
   connection->pending_replies = NULL;
   
-  _dbus_list_clear (&connection->filter_list);
-  
   _dbus_list_foreach (&connection->outgoing_messages,
                       free_outgoing_message,
                      connection);
@@ -2816,11 +2801,6 @@ _dbus_connection_last_unref (DBusConnection *connection)
 
   _dbus_rmutex_free_at_location (&connection->mutex);
 
-#ifdef DBUS_ENABLE_SMACK
-  if (connection->peer_smack_label)
-    free (connection->peer_smack_label);
-#endif
-
   dbus_free (connection);
 }
 
@@ -2863,8 +2843,8 @@ dbus_connection_unref (DBusConnection *connection)
         {
           _dbus_warn_check_failed ("The last reference on a connection was dropped without closing the connection. This is a bug in an application. See dbus_connection_unref() documentation for details.\n%s",
                                    connection->shareable ?
-                                   "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection.\n" : 
-                                    "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.\n");
+                                   "Most likely, the application called unref() too many times and removed a reference belonging to libdbus, since this is a shared connection." :
+                                    "Most likely, the application was supposed to call dbus_connection_close(), since this is a private connection.");
           return;
         }
 #endif
@@ -2971,7 +2951,7 @@ dbus_connection_close (DBusConnection *connection)
     {
       CONNECTION_UNLOCK (connection);
 
-      _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.\n");
+      _dbus_warn_check_failed ("Applications must not close shared connections - see dbus_connection_close() docs. This is a bug in the application.");
       return;
     }
 #endif
@@ -3089,7 +3069,7 @@ dbus_connection_get_is_anonymous (DBusConnection *connection)
  * dbus_bus_get_id() instead (which is just a convenience wrapper
  * around the org.freedesktop.DBus.GetId method invoked on the bus).
  *
- * You can also get a machine ID; see dbus_get_local_machine_id() to
+ * You can also get a machine ID; see dbus_try_get_local_machine_id() to
  * get the machine you are on.  There isn't a convenience wrapper, but
  * you can invoke org.freedesktop.DBus.Peer.GetMachineId on any peer
  * to get the machine ID on the other end.
@@ -3466,6 +3446,7 @@ dbus_connection_send_with_reply (DBusConnection     *connection,
       return TRUE;
     }
 
+  _dbus_message_set_timeout_ms(message, timeout_milliseconds);
   pending = _dbus_pending_call_new_unlocked (connection,
                                              timeout_milliseconds,
                                              reply_handler_timeout);
@@ -3575,6 +3556,22 @@ dbus_connection_send_with_reply_and_block (DBusConnection     *connection,
   _dbus_return_val_if_fail (timeout_milliseconds >= 0 || timeout_milliseconds == -1, NULL);
   _dbus_return_val_if_error_is_set (error, NULL);
 
+  if (_dbus_transport_can_send_sync_call (connection->transport))
+    {
+      dbus_int32_t serial;
+
+      /* set serial */
+      serial = dbus_message_get_serial (message);
+      if (serial == 0)
+        {
+          serial = _dbus_connection_get_next_client_serial (connection);
+          dbus_message_set_serial (message, serial);
+        }
+
+      reply = _dbus_transport_send_sync_call (connection->transport, message);
+      goto out;
+    }
+
 #ifdef HAVE_UNIX_FD_PASSING
 
   CONNECTION_LOCK (connection);
@@ -3610,9 +3607,11 @@ dbus_connection_send_with_reply_and_block (DBusConnection     *connection,
   /* call_complete_and_unlock() called from pending_call_block() should
    * always fill this in.
    */
+
+out:
   _dbus_assert (reply != NULL);
   
-   if (dbus_set_error_from_message (error, reply))
+  if (dbus_set_error_from_message (error, reply))
     {
       dbus_message_unref (reply);
       return NULL;
@@ -4357,7 +4356,7 @@ static DBusDispatchStatus
 _dbus_connection_get_dispatch_status_unlocked (DBusConnection *connection)
 {
   HAVE_LOCK_CHECK (connection);
-  if (connection->dispatch_disabled && dbus_connection_get_is_connected(connection))
+  if (connection->dispatch_disabled)
     return DBUS_DISPATCH_COMPLETE;
   else if (connection->n_incoming > 0)
     return DBUS_DISPATCH_DATA_REMAINS;
@@ -4571,12 +4570,14 @@ _dbus_connection_peer_filter_unlocked_no_update (DBusConnection *connection,
       else if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
         {
           dbus_error_free (&error);
+          _dbus_string_free (&uuid);
           goto out;
         }
       else
         {
           ret = dbus_message_new_error (message, error.name, error.message);
           dbus_error_free (&error);
+          _dbus_string_free (&uuid);
 
           if (ret == NULL)
             goto out;
@@ -5316,6 +5317,12 @@ _dbus_connection_get_n_incoming (DBusConnection *connection)
   return connection->n_incoming;
 }
 
+dbus_bool_t
+_dbus_connection_is_overflowed (DBusConnection *connection)
+{
+  return _dbus_transport_get_overflowed (connection->transport);
+}
+
 /**
  * Gets the UNIX user ID of the connection if known.  Returns #TRUE if
  * the uid is filled in.  Always returns #FALSE on non-UNIX platforms
@@ -5396,27 +5403,6 @@ dbus_connection_get_unix_process_id (DBusConnection *connection,
   return result;
 }
 
-#ifdef DBUS_ENABLE_SMACK
-/**
- * Gets the Smack label of the peer at the time when the connection
- * was established. Returns #TRUE if the label is filled in.
- *
- * @param connection the connection
- * @param label return location for the Smack label; returned value is valid as long as the connection exists
- * @returns #TRUE if uid is filled in with a valid process ID
- */
-dbus_bool_t
-dbus_connection_get_smack_label (DBusConnection *connection,
-                                const char **label)
-{
-  _dbus_return_val_if_fail (connection != NULL, FALSE);
-  _dbus_return_val_if_fail (label != NULL, FALSE);
-
-  *label = connection->peer_smack_label;
-  return *label != NULL;
-}
-#endif
-
 /**
  * Gets the ADT audit data of the connection if any.
  * Returns #TRUE if the structure pointer is returned.
@@ -5796,7 +5782,7 @@ dbus_connection_remove_filter (DBusConnection            *connection,
 #ifndef DBUS_DISABLE_CHECKS
   if (filter == NULL)
     {
-      _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added\n",
+      _dbus_warn_check_failed ("Attempt to remove filter function %p user data %p, but no such filter has been added",
                                function, user_data);
       return;
     }
@@ -5915,7 +5901,7 @@ dbus_connection_register_object_path (DBusConnection              *connection,
 
   if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
     {
-      _dbus_warn ("%s\n", error.message);
+      _dbus_warn ("%s", error.message);
       dbus_error_free (&error);
       return FALSE;
     }
@@ -5987,7 +5973,7 @@ dbus_connection_register_fallback (DBusConnection              *connection,
 
   if (dbus_error_has_name (&error, DBUS_ERROR_OBJECT_PATH_IN_USE))
     {
-      _dbus_warn ("%s\n", error.message);
+      _dbus_warn ("%s", error.message);
       dbus_error_free (&error);
       return FALSE;
     }