restructure buggy parse_args routine
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@5898 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
parent
0c082e7e62
commit
0aae19259a
114
cli.c
114
cli.c
|
@ -1067,72 +1067,62 @@ static int handle_help(int fd, int argc, char *argv[]) {
|
||||||
return RESULT_SUCCESS;
|
return RESULT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *parse_args(char *s, int *max, char *argv[])
|
static char *parse_args(char *s, int *argc, char *argv[], int max)
|
||||||
{
|
{
|
||||||
char *dup, *cur;
|
char *dup, *cur;
|
||||||
int x=0;
|
int x = 0;
|
||||||
int quoted=0;
|
int quoted = 0;
|
||||||
int escaped=0;
|
int escaped = 0;
|
||||||
int whitespace=1;
|
int whitespace = 1;
|
||||||
|
|
||||||
dup = strdup(s);
|
if (!(dup = strdup(s)))
|
||||||
if (dup) {
|
return NULL;
|
||||||
cur = dup;
|
|
||||||
while(*s) {
|
cur = dup;
|
||||||
switch(*s) {
|
while (*s) {
|
||||||
case '"':
|
if ((*s == '"') && !escaped) {
|
||||||
/* If it's escaped, put a literal quote */
|
quoted = !quoted;
|
||||||
if (escaped)
|
if (quoted & whitespace) {
|
||||||
goto normal;
|
/* If we're starting a quoted string, coming off white space, start a new argument */
|
||||||
else
|
if (x >= (max - 1)) {
|
||||||
quoted = !quoted;
|
ast_log(LOG_WARNING, "Too many arguments, truncating\n");
|
||||||
if (quoted && whitespace) {
|
break;
|
||||||
/* If we're starting a quote, coming off white space start a new word, too */
|
|
||||||
argv[x++] = cur;
|
|
||||||
whitespace=0;
|
|
||||||
}
|
}
|
||||||
escaped = 0;
|
argv[x++] = cur;
|
||||||
break;
|
whitespace = 0;
|
||||||
case ' ':
|
|
||||||
case '\t':
|
|
||||||
if (!quoted && !escaped) {
|
|
||||||
/* If we're not quoted, mark this as whitespace, and
|
|
||||||
end the previous argument */
|
|
||||||
whitespace = 1;
|
|
||||||
*(cur++) = '\0';
|
|
||||||
} else
|
|
||||||
/* Otherwise, just treat it as anything else */
|
|
||||||
goto normal;
|
|
||||||
break;
|
|
||||||
case '\\':
|
|
||||||
/* If we're escaped, print a literal, otherwise enable escaping */
|
|
||||||
if (escaped) {
|
|
||||||
goto normal;
|
|
||||||
} else {
|
|
||||||
escaped=1;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
normal:
|
|
||||||
if (whitespace) {
|
|
||||||
if (x >= AST_MAX_ARGS -1) {
|
|
||||||
ast_log(LOG_WARNING, "Too many arguments, truncating\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* Coming off of whitespace, start the next argument */
|
|
||||||
argv[x++] = cur;
|
|
||||||
whitespace=0;
|
|
||||||
}
|
|
||||||
*(cur++) = *s;
|
|
||||||
escaped=0;
|
|
||||||
}
|
}
|
||||||
s++;
|
escaped = 0;
|
||||||
|
} else if (((*s == ' ') || (*s == '\t')) && !(quoted || escaped)) {
|
||||||
|
/* If we are not already in whitespace, and not in a quoted string or
|
||||||
|
processing an escape sequence, and just entered whitespace, then
|
||||||
|
finalize the previous argument and remember that we are in whitespace
|
||||||
|
*/
|
||||||
|
if (!whitespace) {
|
||||||
|
*(cur++) = '\0';
|
||||||
|
whitespace = 1;
|
||||||
|
}
|
||||||
|
} else if ((*s == '\\') && !escaped) {
|
||||||
|
escaped = 1;
|
||||||
|
} else {
|
||||||
|
if (whitespace) {
|
||||||
|
/* If we are coming out of whitespace, start a new argument */
|
||||||
|
if (x >= (max - 1)) {
|
||||||
|
ast_log(LOG_WARNING, "Too many arguments, truncating\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
argv[x++] = cur;
|
||||||
|
whitespace = 0;
|
||||||
|
}
|
||||||
|
*(cur++) = *s;
|
||||||
|
escaped = 0;
|
||||||
}
|
}
|
||||||
/* Null terminate */
|
s++;
|
||||||
*(cur++) = '\0';
|
|
||||||
argv[x] = NULL;
|
|
||||||
*max = x;
|
|
||||||
}
|
}
|
||||||
|
/* Null terminate */
|
||||||
|
*(cur++) = '\0';
|
||||||
|
argv[x] = NULL;
|
||||||
|
*argc = x;
|
||||||
|
|
||||||
return dup;
|
return dup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1204,7 +1194,7 @@ static char *__ast_cli_generator(char *text, char *word, int state, int lock)
|
||||||
char matchstr[80];
|
char matchstr[80];
|
||||||
char *fullcmd = NULL;
|
char *fullcmd = NULL;
|
||||||
|
|
||||||
if ((dup = parse_args(text, &x, argv))) {
|
if ((dup = parse_args(text, &x, argv, sizeof(argv) / sizeof(argv[0])))) {
|
||||||
join(matchstr, sizeof(matchstr), argv);
|
join(matchstr, sizeof(matchstr), argv);
|
||||||
if (lock)
|
if (lock)
|
||||||
ast_mutex_lock(&clilock);
|
ast_mutex_lock(&clilock);
|
||||||
|
@ -1277,8 +1267,8 @@ int ast_cli_command(int fd, char *s)
|
||||||
struct ast_cli_entry *e;
|
struct ast_cli_entry *e;
|
||||||
int x;
|
int x;
|
||||||
char *dup;
|
char *dup;
|
||||||
x = AST_MAX_ARGS;
|
|
||||||
if ((dup = parse_args(s, &x, argv))) {
|
if ((dup = parse_args(s, &x, argv, sizeof(argv) / sizeof(argv[0])))) {
|
||||||
/* We need at least one entry, or ignore */
|
/* We need at least one entry, or ignore */
|
||||||
if (x > 0) {
|
if (x > 0) {
|
||||||
ast_mutex_lock(&clilock);
|
ast_mutex_lock(&clilock);
|
||||||
|
|
Loading…
Reference in New Issue