mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2024-12-27 23:22:09 +00:00
MINOR: tools: support for word expansion of environment in parse_line
Allow the syntax "${...[*]}" to expand an environment variable containing several values separated by spaces as individual arguments. A new flag PARSE_OPT_WORD_EXPAND has been added to toggle this feature on parse_line invocation. In case of an invalid syntax, a new error PARSE_ERR_WRONG_EXPAND will be triggered. This feature has been asked on the github issue #165.
This commit is contained in:
parent
ac32b4b98c
commit
fa41cb6792
@ -475,7 +475,10 @@ interpreted only within double quotes. Variables are expanded during the
|
||||
configuration parsing. Variable names must be preceded by a dollar ("$") and
|
||||
optionally enclosed with braces ("{}") similarly to what is done in Bourne
|
||||
shell. Variable names can contain alphanumerical characters or the character
|
||||
underscore ("_") but should not start with a digit.
|
||||
underscore ("_") but should not start with a digit. If the variable contains a
|
||||
list of several values separated by spaces, it can be expanded as individual
|
||||
arguments by enclosing the variable with braces and appending the suffix '[*]'
|
||||
before the closing brace.
|
||||
|
||||
Example:
|
||||
|
||||
|
@ -57,6 +57,7 @@
|
||||
#define PARSE_OPT_DQUOTE 0x00000008 // '"' encloses a string
|
||||
#define PARSE_OPT_ENV 0x00000010 // '$' is followed by environment variables
|
||||
#define PARSE_OPT_INPLACE 0x00000020 // parse and tokenize in-place (src == dst)
|
||||
#define PARSE_OPT_WORD_EXPAND 0x00000040 // '[*]' suffix to expand an environment variable as several individual arguments
|
||||
|
||||
/* return error flags from parse_line() */
|
||||
#define PARSE_ERR_TOOLARGE 0x00000001 // result is too large for initial outlen
|
||||
@ -66,6 +67,7 @@
|
||||
#define PARSE_ERR_HEX 0x00000010 // unparsable hex sequence (at errptr)
|
||||
#define PARSE_ERR_VARNAME 0x00000020 // invalid variable name (at errptr)
|
||||
#define PARSE_ERR_OVERLAP 0x00000040 // output overlaps with input, need to allocate
|
||||
#define PARSE_ERR_WRONG_EXPAND 0x00000080 // unparsable word expansion sequence
|
||||
|
||||
/* special return values for the time parser (parse_time_err()) */
|
||||
#define PARSE_TIME_UNDER ((char *)1)
|
||||
|
@ -1908,7 +1908,8 @@ next_line:
|
||||
outlen = outlinesize;
|
||||
err = parse_line(line, outline, &outlen, args, &arg,
|
||||
PARSE_OPT_ENV | PARSE_OPT_DQUOTE | PARSE_OPT_SQUOTE |
|
||||
PARSE_OPT_BKSLASH | PARSE_OPT_SHARP, &errptr);
|
||||
PARSE_OPT_BKSLASH | PARSE_OPT_SHARP | PARSE_OPT_WORD_EXPAND,
|
||||
&errptr);
|
||||
|
||||
if (err & PARSE_ERR_QUOTE) {
|
||||
size_t newpos = sanitize_for_printing(line, errptr - line, 80);
|
||||
@ -1950,6 +1951,16 @@ next_line:
|
||||
goto next_line;
|
||||
}
|
||||
|
||||
if (err & PARSE_ERR_WRONG_EXPAND) {
|
||||
size_t newpos = sanitize_for_printing(line, errptr - line, 80);
|
||||
|
||||
ha_alert("parsing [%s:%d]: truncated or invalid word expansion sequence at position %d:\n"
|
||||
" %s\n %*s\n", file, linenum, (int)(errptr-thisline+1), line, (int)(newpos+1), "^");
|
||||
err_code |= ERR_ALERT | ERR_FATAL;
|
||||
fatal++;
|
||||
goto next_line;
|
||||
}
|
||||
|
||||
if (err & (PARSE_ERR_TOOLARGE|PARSE_ERR_OVERLAP)) {
|
||||
outlinesize = (outlen + 1023) & -1024;
|
||||
outline = realloc(outline, outlinesize);
|
||||
|
34
src/tools.c
34
src/tools.c
@ -4911,6 +4911,7 @@ uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbarg
|
||||
{
|
||||
char *quote = NULL;
|
||||
char *brace = NULL;
|
||||
char *word_expand = NULL;
|
||||
unsigned char hex1, hex2;
|
||||
size_t outmax = *outlen;
|
||||
int argsmax = *nbargs - 1;
|
||||
@ -5089,6 +5090,19 @@ uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbarg
|
||||
value = getenv(var_name);
|
||||
*in = save_char;
|
||||
|
||||
/* support for '[*]' sequence to force word expansion,
|
||||
* only available inside braces */
|
||||
if (*in == '[' && brace && (opts & PARSE_OPT_WORD_EXPAND)) {
|
||||
word_expand = in++;
|
||||
|
||||
if (*in++ != '*' || *in++ != ']') {
|
||||
err |= PARSE_ERR_WRONG_EXPAND;
|
||||
if (errptr)
|
||||
*errptr = word_expand;
|
||||
goto leave;
|
||||
}
|
||||
}
|
||||
|
||||
if (brace) {
|
||||
if (*in != '}') {
|
||||
/* unmatched brace */
|
||||
@ -5102,9 +5116,25 @@ uint32_t parse_line(char *in, char *out, size_t *outlen, char **args, int *nbarg
|
||||
}
|
||||
|
||||
if (value) {
|
||||
while (*value)
|
||||
EMIT_CHAR(*value++);
|
||||
while (*value) {
|
||||
/* expand as individual parameters on a space character */
|
||||
if (word_expand && isspace(*value)) {
|
||||
EMIT_CHAR(0);
|
||||
++arg;
|
||||
if (arg < argsmax)
|
||||
args[arg] = out + outpos;
|
||||
else
|
||||
err |= PARSE_ERR_TOOMANY;
|
||||
|
||||
/* skip consecutive spaces */
|
||||
while (isspace(*++value))
|
||||
;
|
||||
} else {
|
||||
EMIT_CHAR(*value++);
|
||||
}
|
||||
}
|
||||
}
|
||||
word_expand = NULL;
|
||||
}
|
||||
else {
|
||||
/* any other regular char */
|
||||
|
Loading…
Reference in New Issue
Block a user