make argument handling (esp. of strings) more robust

This commit is contained in:
lukechampine 2013-08-10 20:10:03 -04:00
parent 8e05bcb5f9
commit 1139ca57a5

View File

@ -40,7 +40,7 @@ static struct {
void (*func)(ToxWindow *, char **); void (*func)(ToxWindow *, char **);
} commands[] = { } commands[] = {
{ "accept", 1, cmd_accept }, { "accept", 1, cmd_accept },
{ "add", 2, cmd_add }, { "add", 1, cmd_add },
{ "clear", 0, cmd_clear }, { "clear", 0, cmd_clear },
{ "connect", 3, cmd_connect }, { "connect", 3, cmd_connect },
{ "exit", 0, cmd_quit }, { "exit", 0, cmd_quit },
@ -300,36 +300,54 @@ static void execute(ToxWindow *self, char *u_cmd)
break; break;
cmd[cmd_end + 1] = '\0'; cmd[cmd_end + 1] = '\0';
char *args[4]; /* insert \0 at argument boundaries */
args[0] = strtok(cmd, " "); int numargs = 0;
for (i = 0; i < MAX_STR_SIZE; i++) {
if (cmd[i] == '\"')
while (cmd[++i] != '\"'); /* skip over strings */
if (cmd[i] == ' ') {
cmd[i] = '\0';
numargs++;
}
}
/* excessive arguments */
if (numargs > 3) {
wprintw(self->window, "Invalid command: too many arguments.\n");
return;
}
/* read arguments into array */
char *cmdargs[5];
int pos = 0;
for (i = 0; i < 5; i++) {
cmdargs[i] = cmd + pos;
pos += strlen(cmdargs[i]) + 1;
}
/* no input */ /* no input */
if (!args[0]) if (strlen(cmdargs[0]) == 0)
return; return;
/* match input to command list */ /* match input to command list */
for (i = 0; i < NUM_COMMANDS; i++) { for (i = 0; i < NUM_COMMANDS; i++) {
if (!strcmp(args[0], commands[i].name)) { if (!strcmp(cmdargs[0], commands[i].name)) {
/* read in arguments */ /* check for missing arguments */
int j; int j;
for (j = 1; j <= commands[i].numargs; j++) { for (j = 0; j <= commands[i].numargs; j++) {
args[j] = strtok(NULL, " "); if (strlen(cmdargs[j]) == 0) {
/* check for missing arguments */
/* add is special because it can take either 1 or 2 arguments */
if (strcmp(args[0], "add") != 0 && args[j] == NULL) {
wprintw(self->window, "Invalid command: %s expected %d arguments, got %d.\n", wprintw(self->window, "Invalid command: %s expected %d arguments, got %d.\n",
commands[i].name, commands[i].numargs, j - 1); commands[i].name, commands[i].numargs, j - 1);
return; return;
} }
} }
/* check for excess arguments */ /* check for excess arguments */
/* add is special because the add message may contain spaces */ if (strcmp(cmdargs[0], "add") && strlen(cmdargs[j]) != 0) {
if (strcmp(args[0], "add") != 0 && strtok(NULL, " ") != NULL) {
wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name); wprintw(self->window, "Invalid command: too many arguments to %s.\n", commands[i].name);
return; return;
} }
/* pass arguments to command function */ /* pass arguments to command function */
(commands[i].func)(self, args); (commands[i].func)(self, cmdargs);
return; return;
} }
} }