Properly handle quoted strings in command parser.

This commit is contained in:
Felicity Tarnell 2014-03-05 15:20:53 +00:00
parent 7a0aca347e
commit 5db1e9cdbb
2 changed files with 46 additions and 5 deletions

45
tts.c
View file

@ -2418,19 +2418,51 @@ const WCHAR *p, *q;
for (;;) { for (;;) {
ptrdiff_t sz; ptrdiff_t sz;
int qskip = 0;
/* Skip leading whitespace */
while (ISSPACE(*p)) while (ISSPACE(*p))
p++; p++;
/* End of string - no more arguments */
if (!*p) if (!*p)
break; break;
q = p; q = p;
/* Find the next seperator */ if (*q == '"') {
while (!ISSPACE(*q) && *q) /* Quoted string - scan for end of string */
q++; int isbsl = 0;
p++;
while (*++q) {
/* Handle escaping with backslash; currently works but the \ isn't
* removed from the string.
*/
if (*q == '\\') {
isbsl = 1;
continue;
}
if (!isbsl && (*q == '"'))
break;
isbsl = 0;
}
/* At this point, *q == '"'. If it's NUL instead, then the
* string was not terminated with a closing '"' before the end
* of the line. We could give an error here, but it seems
* more useful to just accept it.
*/
if (*q == '"')
qskip = 1;
} else {
/* Not quoted - just find the next whitespace */
while (!ISSPACE(*q) && *q)
q++;
}
/* Copy the argument (which is sz bytes long) into the result array */
sz = (q - p); sz = (q - p);
*res = realloc(*res, sizeof(WCHAR *) * (ntoks + 1)); *res = realloc(*res, sizeof(WCHAR *) * (ntoks + 1));
(*res)[ntoks] = malloc(sizeof(WCHAR) * sz + 1); (*res)[ntoks] = malloc(sizeof(WCHAR) * sz + 1);
@ -2438,9 +2470,16 @@ const WCHAR *p, *q;
(*res)[ntoks][sz] = 0; (*res)[ntoks][sz] = 0;
ntoks++; ntoks++;
if (qskip)
q += qskip;
while (ISSPACE(*q)) while (ISSPACE(*q))
q++; q++;
/*
* q is the start of the next token (with leading whitespace); reset
* p to process the next argument.
*/
if (!*q) if (!*q)
break; break;
p = q; p = q;

View file

@ -15,11 +15,13 @@
#### Miscellaneous options #### Miscellaneous options
# #
# If set, show billable time in each daily summary. # If set, show billable time in each daily summary.
#set show_billable 1 #set show_billable 1
# If this is set, and a newly added entry contains this string, the entry wil # If this is set, and a newly added entry contains this string, the entry wil
# be automatically marked as non-billable. The string can only be a single # be automatically marked as non-billable. If the string contains whitespace,
# word and must not be put in quotes. # it should be wrapped in "quote marks".
#set auto_non_billable [INT] #set auto_non_billable [INT]
#### Bindings #### Bindings