Allow braceless variables to be expanded

(Only in environment.d files.)

We have only basic compatibility with shell syntax, but specifying variables
without using braces is probably more common, and I think a lot of people would
be surprised if this didn't work.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2017-02-20 23:30:50 -05:00
parent cb4499d005
commit ccad1fd07c
6 changed files with 91 additions and 11 deletions
+43 -2
View File
@@ -523,7 +523,8 @@ char *replace_env(const char *format, char **env, unsigned flags) {
enum {
WORD,
CURLY,
VARIABLE
VARIABLE,
VARIABLE_RAW,
} state = WORD;
const char *e, *word = format;
@@ -563,6 +564,18 @@ char *replace_env(const char *format, char **env, unsigned flags) {
word = e+1;
state = WORD;
} else if (flags & REPLACE_ENV_ALLOW_BRACELESS && strchr(VALID_CHARS_ENV_NAME, *e)) {
k = strnappend(r, word, e-word-1);
if (!k)
return NULL;
free(r);
r = k;
word = e-1;
state = VARIABLE_RAW;
} else
state = WORD;
break;
@@ -584,10 +597,38 @@ char *replace_env(const char *format, char **env, unsigned flags) {
state = WORD;
}
break;
case VARIABLE_RAW:
assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
if (!strchr(VALID_CHARS_ENV_NAME, *e)) {
const char *t;
t = strv_env_get_n(env, word+1, e-word-1, flags);
k = strappend(r, t);
if (!k)
return NULL;
free(r);
r = k;
word = e--;
state = WORD;
}
break;
}
}
return strnappend(r, word, e-word);
if (state == VARIABLE_RAW) {
const char *t;
assert(flags & REPLACE_ENV_ALLOW_BRACELESS);
t = strv_env_get_n(env, word+1, e-word-1, flags);
return strappend(r, t);
} else
return strnappend(r, word, e-word);
}
char **replace_env_argv(char **argv, char **env) {
+1
View File
@@ -31,6 +31,7 @@ bool env_assignment_is_valid(const char *e);
enum {
REPLACE_ENV_USE_ENVIRONMENT = 1u,
REPLACE_ENV_ALLOW_BRACELESS = 2u,
};
char *replace_env(const char *format, char **env, unsigned flags);
+6 -1
View File
@@ -773,7 +773,8 @@ static int merge_env_file_push(
assert(env);
expanded_value = replace_env(value, *env, REPLACE_ENV_USE_ENVIRONMENT);
expanded_value = replace_env(value, *env,
REPLACE_ENV_USE_ENVIRONMENT|REPLACE_ENV_ALLOW_BRACELESS);
if (!expanded_value)
return -ENOMEM;
@@ -787,6 +788,10 @@ int merge_env_file(
FILE *f,
const char *fname) {
/* NOTE: this function supports braceful and braceless variable expansions,
* unlike other exported parsing functions.
*/
return parse_env_file_internal(f, fname, NEWLINE, merge_env_file_push, env, NULL);
}