command: relax requirements for unquoted words

Allow most printable characters in unquoted words.  The tokenizer
patch introduced very strict requirements for command parameters -
those were undocumented, and we're reverting the strictness now.
This commit is contained in:
Max Kellermann 2009-09-25 00:53:15 +02:00
parent 89ba540e6d
commit 7542ec4f20
3 changed files with 75 additions and 6 deletions

View File

@ -1959,7 +1959,7 @@ command_process(struct client *client, unsigned num, char *line)
while (argc < (int)G_N_ELEMENTS(argv) &&
(argv[argc] =
tokenizer_next_word_or_string(&line, &error)) != NULL)
tokenizer_next_param(&line, &error)) != NULL)
++argc;
/* some error checks; we have to set current_command because

View File

@ -90,6 +90,60 @@ tokenizer_next_word(char **input_p, GError **error_r)
return word;
}
static inline bool
valid_unquoted_char(char ch)
{
return (unsigned char)ch > 0x20 && ch != '"' && ch != '\'';
}
char *
tokenizer_next_unquoted(char **input_p, GError **error_r)
{
char *word, *input;
assert(input_p != NULL);
assert(*input_p != NULL);
word = input = *input_p;
if (*input == 0)
return NULL;
/* check the first character */
if (!valid_unquoted_char(*input)) {
g_set_error(error_r, tokenizer_quark(), 0,
"Invalid unquoted character");
return NULL;
}
/* now iterate over the other characters until we find a
whitespace or end-of-string */
while (*++input != 0) {
if (g_ascii_isspace(*input)) {
/* a whitespace: the word ends here */
*input = 0;
/* skip all following spaces, too */
input = g_strchug(input + 1);
break;
}
if (!valid_unquoted_char(*input)) {
*input_p = input;
g_set_error(error_r, tokenizer_quark(), 0,
"Invalid unquoted character");
return NULL;
}
}
/* end of string: the string is already null-terminated
here */
*input_p = input;
return word;
}
char *
tokenizer_next_string(char **input_p, GError **error_r)
{
@ -155,7 +209,7 @@ tokenizer_next_string(char **input_p, GError **error_r)
}
char *
tokenizer_next_word_or_string(char **input_p, GError **error_r)
tokenizer_next_param(char **input_p, GError **error_r)
{
assert(input_p != NULL);
assert(*input_p != NULL);
@ -163,5 +217,5 @@ tokenizer_next_word_or_string(char **input_p, GError **error_r)
if (**input_p == '"')
return tokenizer_next_string(input_p, error_r);
else
return tokenizer_next_word(input_p, error_r);
return tokenizer_next_unquoted(input_p, error_r);
}

View File

@ -36,6 +36,20 @@
char *
tokenizer_next_word(char **input_p, GError **error_r);
/**
* Reads the next unquoted word from the input string. This function
* modifies the input string.
*
* @param input_p the input string; this function returns a pointer to
* the first non-whitespace character of the following token
* @param error_r if this function returns NULL and **input_p!=0, it
* optionally provides a GError object in this argument
* @return a pointer to the null-terminated word, or NULL on error or
* end of line
*/
char *
tokenizer_next_unquoted(char **input_p, GError **error_r);
/**
* Reads the next quoted string from the input string. A backslash
* escapes the following character. This function modifies the input
@ -52,8 +66,9 @@ char *
tokenizer_next_string(char **input_p, GError **error_r);
/**
* Reads the next word or quoted string from the input. This is a
* wrapper for tokenizer_next_word() and tokenizer_next_string().
* Reads the next unquoted word or quoted string from the input. This
* is a wrapper for tokenizer_next_unquoted() and
* tokenizer_next_string().
*
* @param input_p the input string; this function returns a pointer to
* the first non-whitespace character of the following token
@ -63,6 +78,6 @@ tokenizer_next_string(char **input_p, GError **error_r);
* or end of line
*/
char *
tokenizer_next_word_or_string(char **input_p, GError **error_r);
tokenizer_next_param(char **input_p, GError **error_r);
#endif