Fix a potential null pointer deref & a potential memory leak,
authorJason Molenda <jmolenda@apple.com>
Thu, 16 Oct 2014 02:08:11 +0000 (02:08 +0000)
committerJason Molenda <jmolenda@apple.com>
Thu, 16 Oct 2014 02:08:11 +0000 (02:08 +0000)
also reformat to conform to the usual lldb coding conventions
a little better.
clang static analyzer fixit.

llvm-svn: 219893

lldb/source/Host/macosx/launcherXPCService/main.mm

index 768faef..397d3a5 100644 (file)
@@ -23,7 +23,8 @@
 int _validate_authorization(xpc_object_t message);
 
 // Returns 0 if successful.
-int _setup_posixspawn_attributes_file_actions(xpc_object_t message, posix_spawnattr_t *attr, posix_spawn_file_actions_t *file_actions)
+int
+_setup_posixspawn_attributes_file_actions(xpc_object_t message, posix_spawnattr_t *attr, posix_spawn_file_actions_t *file_actions)
 {
     *attr = 0;
     
@@ -32,7 +33,8 @@ int _setup_posixspawn_attributes_file_actions(xpc_object_t message, posix_spawna
         return errorCode;
     
     cpu_type_t cpuType = (cpu_type_t)xpc_dictionary_get_int64(message, LauncherXPCServiceCPUTypeKey);
-    if (cpuType == -2) {
+    if (cpuType == -2)
+    {
         cpuType= CPU_TYPE_ANY;
     }
     size_t realCount;
@@ -94,23 +96,27 @@ int _setup_posixspawn_attributes_file_actions(xpc_object_t message, posix_spawna
     return errorCode;
 }
 
-bool extract_args(xpc_object_t message, const char *prefix, const char ***argsOut)
+bool
+extract_args(xpc_object_t message, const char *prefix, const char ***argsOut)
 {
     char buf[50]; // long enough for 'argXXX'
     memset(buf, 0, 50);
     sprintf(buf, "%sCount", prefix);
     int argsCount = (int)xpc_dictionary_get_int64(message, buf);
-    if (argsCount == 0) {
+    if (argsCount == 0)
+    {
         return true;
     }
     
     const char **argsp = NULL;
     argsp = (const char **)malloc((argsCount+1) * sizeof(argsp[0]));
-    if (argsp == NULL) {
+    if (argsp == NULL)
+    {
         return false;
     }
     
-    for (int i=0; i<argsCount; i++) {
+    for (int i=0; i<argsCount; i++)
+    {
         memset(buf, 0, 50);
         sprintf(buf, "%s%i", prefix, i);
         const char *arg = xpc_dictionary_get_string(message, buf);
@@ -123,21 +129,28 @@ bool extract_args(xpc_object_t message, const char *prefix, const char ***argsOu
 }
 
 // Returns 0 if successful.
-int get_args(xpc_object_t message, const char **path, const char ***argsOut, const char ***envOut)
+int
+get_args(xpc_object_t message, const char **path, const char ***argsOut, const char ***envOut)
 {
-    if (!extract_args(message, LauncherXPCServiceArgPrefxKey, argsOut)) {
+    if (!extract_args(message, LauncherXPCServiceArgPrefxKey, argsOut))
+    {
         return 1;
     }
-    *path = (*argsOut)[0];
+    if (path && *path && argsOut && *argsOut)
+    {
+        *path = (*argsOut)[0];
+    }
     
-    if (!extract_args(message, LauncherXPCServiceEnvPrefxKey, envOut)) {
+    if (!extract_args(message, LauncherXPCServiceEnvPrefxKey, envOut))
+    {
         return 2;
     }
     
     return 0;
 }
 
-void _wait_for_child_exit(pid_t childPID)
+void
+_wait_for_child_exit(pid_t childPID)
 {
     dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
     dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_PROC, childPID, DISPATCH_PROC_EXIT, queue);
@@ -153,7 +166,8 @@ void _wait_for_child_exit(pid_t childPID)
             dispatch_source_cancel(source);
             
             int status, ret;
-            do {
+            do
+            {
                 ret = waitpid(childPID, &status, 0);
             } while (ret < 0 && errno == EINTR);
             
@@ -162,20 +176,27 @@ void _wait_for_child_exit(pid_t childPID)
     }
 }
 
-static void launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t event) 
+static void
+launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t event)
 {
        xpc_type_t type = xpc_get_type(event);
-       if (type == XPC_TYPE_ERROR) {
-               if (event == XPC_ERROR_CONNECTION_INVALID) {
+       if (type == XPC_TYPE_ERROR)
+    {
+               if (event == XPC_ERROR_CONNECTION_INVALID)
+        {
                        // The client process on the other end of the connection has either
                        // crashed or cancelled the connection. After receiving this error,
                        // the connection is in an invalid state, and you do not need to
                        // call xpc_connection_cancel(). Just tear down any associated state
                        // here.
-               } else if (event == XPC_ERROR_TERMINATION_IMMINENT) {
+               }
+        else if (event == XPC_ERROR_TERMINATION_IMMINENT)
+        {
                        // Handle per-connection termination cleanup.
                }
-       } else {
+       }
+    else
+    {
                assert(type == XPC_TYPE_DICTIONARY);
                // Handle the message.
         
@@ -192,7 +213,8 @@ static void launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t e
          */
         int errorType = 100;
         int errorCode = _validate_authorization(event);
-        if (!errorCode) {
+        if (!errorCode)
+        {
             errorType = 101;
             errorCode = _setup_posixspawn_attributes_file_actions(event, &attributes, &file_actions);
             if (!errorCode) {
@@ -201,24 +223,28 @@ static void launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t e
                 const char **envp = NULL;
                 errorType = 102;
                 errorCode = get_args(event, &path, &argvp, &envp);
-                if (!errorCode) {
+                if (!errorCode)
+                {
                     errorType = 103;
                     errorCode = posix_spawn(&childPID, path, &file_actions, &attributes, (char * const *)argvp, (char * const *)envp);
                     
-                    if (argvp) free(argvp);
-                    if (envp) free(envp);
-                    
-                    if (errorCode == 0) {
+                    if (errorCode == 0)
+                    {
                         _wait_for_child_exit(childPID);
                     }
                 }
+                if (argvp)
+                    free(argvp);
+                if (envp)
+                    free(envp);
             }
         }
         
        xpc_object_t reply = xpc_dictionary_create_reply(event);
         
         xpc_dictionary_set_int64(reply, LauncherXPCServiceChildPIDKey, childPID);
-        if (!childPID) {
+        if (!childPID)
+        {
             xpc_dictionary_set_int64(reply, LauncherXPCServiceErrorTypeKey, errorType);            
             xpc_dictionary_set_int64(reply, LauncherXPCServiceCodeTypeKey, errorCode);            
         }
@@ -228,7 +254,8 @@ static void launcherXPC_peer_event_handler(xpc_connection_t peer, xpc_object_t e
        }
 }
 
-static void launcherXPC_event_handler(xpc_connection_t peer) 
+static void
+launcherXPC_event_handler(xpc_connection_t peer)
 {
        // By defaults, new connections will target the default dispatch
        // concurrent queue.
@@ -242,7 +269,8 @@ static void launcherXPC_event_handler(xpc_connection_t peer)
        xpc_connection_resume(peer);
 }
 
-int main(int argc, const char *argv[])
+int
+main(int argc, const char *argv[])
 {
        xpc_main(launcherXPC_event_handler);
        return 0;