Code auditing weekend results and fixes committing.
[silc.git] / lib / silcclient / command_reply.c
index 51716566cbf05f438ea72fd3cb553fd07f375cad..b75c78b98da809bc64b9e4c6cd4d387192c696a8 100644 (file)
@@ -229,6 +229,10 @@ silc_client_command_reply_whois_print(SilcClientCommandReplyContext cmd,
   }
   
   client_id = silc_id_payload_parse_id(id_data, len);
+  if (!client_id) {
+    COMMAND_REPLY_ERROR;
+    return;
+  }
   
   nickname = silc_argument_get_arg_type(cmd->args, 3, &len);
   if (nickname) {
@@ -410,6 +414,8 @@ SILC_CLIENT_CMD_REPLY_FUNC(identify)
     if (!id_data)
       goto out;
     client_id = silc_id_payload_parse_id(id_data, len);
+    if (!client_id)
+      goto out;
 
     nickname = silc_argument_get_arg_type(cmd->args, 3, NULL);
     username = silc_argument_get_arg_type(cmd->args, 4, NULL);
@@ -495,6 +501,10 @@ SILC_CLIENT_CMD_REPLY_FUNC(nick)
   /* Take received Client ID */
   tmp = silc_argument_get_arg_type(cmd->args, 2, &len);
   idp = silc_id_payload_parse_data(tmp, len);
+  if (!idp) {
+    COMMAND_REPLY_ERROR;
+    goto out;
+  }
   silc_client_receive_new_id(cmd->client, cmd->sock, idp);
     
   /* Notify application */
@@ -551,6 +561,8 @@ SILC_CLIENT_CMD_REPLY_FUNC(topic)
     goto out;
 
   channel_id = silc_id_payload_parse_id(tmp, len);
+  if (!channel_id)
+    goto out;
 
   /* Get the channel name */
   if (!silc_idcache_find_by_id_one(conn->channel_cache, (void *)channel_id,
@@ -681,7 +693,12 @@ SILC_CLIENT_CMD_REPLY_FUNC(ping)
   }
 
   curtime = time(NULL);
-  id = silc_id_str2id(cmd->packet->src_id, cmd->packet->src_id_type);
+  id = silc_id_str2id(cmd->packet->src_id, cmd->packet->src_id_len,
+                     cmd->packet->src_id_type);
+  if (!id) {
+    COMMAND_REPLY_ERROR;
+    goto out;
+  }
 
   for (i = 0; i < conn->ping_count; i++) {
     if (!SILC_ID_SERVER_COMPARE(conn->ping[i].dest_id, id)) {
@@ -767,6 +784,11 @@ SILC_CLIENT_CMD_REPLY_FUNC(join)
     goto out;
   }
   idp = silc_id_payload_parse_data(tmp, len);
+  if (!idp) {
+    COMMAND_REPLY_ERROR;
+    silc_free(channel_name);
+    goto out;
+  }
 
   /* Get channel mode */
   tmp = silc_argument_get_arg_type(cmd->args, 4, NULL);
@@ -948,6 +970,10 @@ SILC_CLIENT_CMD_REPLY_FUNC(cumode)
     goto out;
   }
   client_id = silc_id_payload_parse_id(id, len);
+  if (!client_id) {
+    COMMAND_REPLY_ERROR;
+    goto out;
+  }
   
   /* Get client entry */
   if (!silc_idcache_find_by_id_one(conn->client_cache, (void *)client_id,
@@ -1050,6 +1076,8 @@ SILC_CLIENT_CMD_REPLY_FUNC(users)
   if (!tmp)
     goto out;
   channel_id = silc_id_payload_parse_id(tmp, tmp_len);
+  if (!channel_id)
+    goto out;
 
   /* Get the list count */
   tmp = silc_argument_get_arg_type(cmd->args, 3, &tmp_len);
@@ -1103,11 +1131,11 @@ SILC_CLIENT_CMD_REPLY_FUNC(users)
     SILC_GET16_MSB(idp_len, client_id_list->data + 2);
     idp_len += 4;
     client_id = silc_id_payload_parse_id(client_id_list->data, idp_len);
-    silc_buffer_pull(client_id_list, idp_len);
+    if (!client_id)
+      continue;
 
     /* Mode */
     SILC_GET32_MSB(mode, client_mode_list->data);
-    silc_buffer_pull(client_mode_list, 4);
 
     /* Check if we have this client cached already. */
     if (!silc_idcache_find_by_id_one(conn->client_cache, (void *)client_id,
@@ -1135,6 +1163,9 @@ SILC_CLIENT_CMD_REPLY_FUNC(users)
       silc_free(client_id);
       id_cache = NULL;
     }
+
+    silc_buffer_pull(client_id_list, idp_len);
+    silc_buffer_pull(client_mode_list, 4);
   }
 
   /* Query the client information from server if the list included clients
@@ -1160,8 +1191,6 @@ SILC_CLIENT_CMD_REPLY_FUNC(users)
     if (channel_id)
       silc_free(channel_id);
 
-    for (i = 0; i < res_argc; i++)
-      silc_free(res_argv[i]);
     silc_free(res_argv);
     silc_free(res_argv_lens);
     silc_free(res_argv_types);
@@ -1171,54 +1200,7 @@ SILC_CLIENT_CMD_REPLY_FUNC(users)
   /* We have all the clients on the channel cached now. Create a nice
      output for user interface and notify application. */
 
-  if (cmd->callback) {
-    /* User has called USERS command on user interface. */
-    cmd->client->ops->say(cmd->client, conn, "Users on %s", 
-                         channel->channel_name);
-    
-    silc_list_start(channel->clients);
-    while ((chu = silc_list_get(channel->clients)) != SILC_LIST_END) {
-      SilcClientEntry e = chu->client;
-      char *m, tmp[80], line[80], len1;
-
-      memset(line, 0, sizeof(line));
-      memset(tmp, 0, sizeof(tmp));
-      m = silc_client_chumode_char(chu->mode);
-
-      strcat(line, " ");
-      strcat(line, e->nickname);
-      strcat(line, e->server ? "@" : "");
-
-      len1 = 0;
-      if (e->server)
-       len1 = strlen(e->server);
-      strncat(line, e->server ? e->server : "", len1 > 30 ? 30 : len1);
-
-      len1 = strlen(line);
-      if (len1 >= 30) {
-       memset(&line[29], 0, len1 - 29);
-      } else {
-       for (i = 0; i < 30 - len1 - 1; i++)
-         strcat(line, " ");
-      }
-
-      strcat(line, "  H");
-      strcat(tmp, m ? m : "");
-      strcat(line, tmp);
-
-      if (strlen(tmp) < 5)
-       for (i = 0; i < 5 - strlen(tmp); i++)
-         strcat(line, " ");
-
-      strcat(line, e->username ? e->username : "");
-
-      cmd->client->ops->say(cmd->client, conn, "%s", line);
-
-      if (m)
-       silc_free(m);
-    }
-
-  } else {
+  if (!cmd->callback) {
     /* Server has sent us USERS reply even when we haven't actually sent
        USERS command. This is normal behaviour when joining to a channel.
        Display some nice information on the user interface. */