mirror of
https://github.com/systemd/systemd.git
synced 2024-11-01 09:21:26 +03:00
util-lib: follow shell syntax for escape in quotes
Fixes #10659. This changes the behaviour of parsing environment files to more closely follow POSIX shell standards. This has the effect that these variables defined in a file: VAR1='\value' VAR2="\value" Are now interpreted as `\value` instead of interpreting the `\` character and interpreting them as `value`. For more information about the behaviour followed, see: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_02
This commit is contained in:
parent
80aff27aeb
commit
e4a8db1fbd
@ -35,7 +35,6 @@ static int parse_env_file_internal(
|
||||
VALUE,
|
||||
VALUE_ESCAPE,
|
||||
SINGLE_QUOTE_VALUE,
|
||||
SINGLE_QUOTE_VALUE_ESCAPE,
|
||||
DOUBLE_QUOTE_VALUE,
|
||||
DOUBLE_QUOTE_VALUE_ESCAPE,
|
||||
COMMENT,
|
||||
@ -186,8 +185,6 @@ static int parse_env_file_internal(
|
||||
case SINGLE_QUOTE_VALUE:
|
||||
if (c == '\'')
|
||||
state = PRE_VALUE;
|
||||
else if (c == '\\')
|
||||
state = SINGLE_QUOTE_VALUE_ESCAPE;
|
||||
else {
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
@ -197,17 +194,6 @@ static int parse_env_file_internal(
|
||||
|
||||
break;
|
||||
|
||||
case SINGLE_QUOTE_VALUE_ESCAPE:
|
||||
state = SINGLE_QUOTE_VALUE;
|
||||
|
||||
if (!strchr(NEWLINE, c)) {
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
|
||||
value[n_value++] = c;
|
||||
}
|
||||
break;
|
||||
|
||||
case DOUBLE_QUOTE_VALUE:
|
||||
if (c == '\"')
|
||||
state = PRE_VALUE;
|
||||
@ -225,12 +211,17 @@ static int parse_env_file_internal(
|
||||
case DOUBLE_QUOTE_VALUE_ESCAPE:
|
||||
state = DOUBLE_QUOTE_VALUE;
|
||||
|
||||
if (!strchr(NEWLINE, c)) {
|
||||
if (c == '"') {
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+2))
|
||||
return -ENOMEM;
|
||||
|
||||
value[n_value++] = '"';
|
||||
} else if (!strchr(NEWLINE, c)) {
|
||||
if (!GREEDY_REALLOC(value, value_alloc, n_value+3))
|
||||
return -ENOMEM;
|
||||
value[n_value++] = '\\';
|
||||
value[n_value++] = c;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case COMMENT:
|
||||
@ -253,7 +244,6 @@ static int parse_env_file_internal(
|
||||
VALUE,
|
||||
VALUE_ESCAPE,
|
||||
SINGLE_QUOTE_VALUE,
|
||||
SINGLE_QUOTE_VALUE_ESCAPE,
|
||||
DOUBLE_QUOTE_VALUE,
|
||||
DOUBLE_QUOTE_VALUE_ESCAPE)) {
|
||||
|
||||
|
@ -26,7 +26,8 @@ static void test_parse_env_file(void) {
|
||||
p[] = "/tmp/test-fileio-out-XXXXXX";
|
||||
FILE *f;
|
||||
_cleanup_free_ char *one = NULL, *two = NULL, *three = NULL, *four = NULL, *five = NULL,
|
||||
*six = NULL, *seven = NULL, *eight = NULL, *nine = NULL, *ten = NULL;
|
||||
*six = NULL, *seven = NULL, *eight = NULL, *nine = NULL, *ten = NULL,
|
||||
*eleven = NULL, *twelve = NULL, *thirteen = NULL;
|
||||
_cleanup_strv_free_ char **a = NULL, **b = NULL;
|
||||
char **i;
|
||||
unsigned k;
|
||||
@ -43,7 +44,7 @@ static void test_parse_env_file(void) {
|
||||
"three = \"333\n"
|
||||
"xxxx\"\n"
|
||||
"four = \'44\\\"44\'\n"
|
||||
"five = \'55\\\'55\' \"FIVE\" cinco \n"
|
||||
"five = \"55\\\"55\" \"FIVE\" cinco \n"
|
||||
"six = seis sechs\\\n"
|
||||
" sis\n"
|
||||
"seven=\"sevenval\" #nocomment\n"
|
||||
@ -51,7 +52,10 @@ static void test_parse_env_file(void) {
|
||||
"export nine=nineval\n"
|
||||
"ten=ignored\n"
|
||||
"ten=ignored\n"
|
||||
"ten=", f);
|
||||
"ten=\n"
|
||||
"eleven=\\value\n"
|
||||
"twelve=\"\\value\"\n"
|
||||
"thirteen='\\value'", f);
|
||||
|
||||
fflush(f);
|
||||
fclose(f);
|
||||
@ -65,14 +69,17 @@ static void test_parse_env_file(void) {
|
||||
assert_se(streq_ptr(a[0], "one=BAR"));
|
||||
assert_se(streq_ptr(a[1], "two=bar"));
|
||||
assert_se(streq_ptr(a[2], "three=333\nxxxx"));
|
||||
assert_se(streq_ptr(a[3], "four=44\"44"));
|
||||
assert_se(streq_ptr(a[4], "five=55\'55FIVEcinco"));
|
||||
assert_se(streq_ptr(a[3], "four=44\\\"44"));
|
||||
assert_se(streq_ptr(a[4], "five=55\"55FIVEcinco"));
|
||||
assert_se(streq_ptr(a[5], "six=seis sechs sis"));
|
||||
assert_se(streq_ptr(a[6], "seven=sevenval#nocomment"));
|
||||
assert_se(streq_ptr(a[7], "eight=eightval #nocomment"));
|
||||
assert_se(streq_ptr(a[8], "export nine=nineval"));
|
||||
assert_se(streq_ptr(a[9], "ten="));
|
||||
assert_se(a[10] == NULL);
|
||||
assert_se(streq_ptr(a[10], "eleven=value"));
|
||||
assert_se(streq_ptr(a[11], "twelve=\\value"));
|
||||
assert_se(streq_ptr(a[12], "thirteen=\\value"));
|
||||
assert_se(a[13] == NULL);
|
||||
|
||||
strv_env_clean(a);
|
||||
|
||||
@ -93,7 +100,10 @@ static void test_parse_env_file(void) {
|
||||
"seven", &seven,
|
||||
"eight", &eight,
|
||||
"export nine", &nine,
|
||||
"ten", &ten);
|
||||
"ten", &ten,
|
||||
"eleven", &eleven,
|
||||
"twelve", &twelve,
|
||||
"thirteen", &thirteen);
|
||||
|
||||
assert_se(r >= 0);
|
||||
|
||||
@ -107,17 +117,23 @@ static void test_parse_env_file(void) {
|
||||
log_info("eight=[%s]", strna(eight));
|
||||
log_info("export nine=[%s]", strna(nine));
|
||||
log_info("ten=[%s]", strna(nine));
|
||||
log_info("eleven=[%s]", strna(eleven));
|
||||
log_info("twelve=[%s]", strna(twelve));
|
||||
log_info("thirteen=[%s]", strna(thirteen));
|
||||
|
||||
assert_se(streq(one, "BAR"));
|
||||
assert_se(streq(two, "bar"));
|
||||
assert_se(streq(three, "333\nxxxx"));
|
||||
assert_se(streq(four, "44\"44"));
|
||||
assert_se(streq(five, "55\'55FIVEcinco"));
|
||||
assert_se(streq(four, "44\\\"44"));
|
||||
assert_se(streq(five, "55\"55FIVEcinco"));
|
||||
assert_se(streq(six, "seis sechs sis"));
|
||||
assert_se(streq(seven, "sevenval#nocomment"));
|
||||
assert_se(streq(eight, "eightval #nocomment"));
|
||||
assert_se(streq(nine, "nineval"));
|
||||
assert_se(ten == NULL);
|
||||
assert_se(streq(eleven, "value"));
|
||||
assert_se(streq(twelve, "\\value"));
|
||||
assert_se(streq(thirteen, "\\value"));
|
||||
|
||||
{
|
||||
/* prepare a temporary file to write the environment to */
|
||||
|
Loading…
Reference in New Issue
Block a user