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:
+43
-2
@@ -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) {
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user