Skip to content
This repository was archived by the owner on Nov 17, 2020. It is now read-only.

Commit 23191bb

Browse files
authored
Merge pull request #417 from rabbitmq/fix-conf_env_file-output-parsing
rabbit_env: Fix parsing of $CONF_ENV_FILE output
2 parents c5ef0b9 + bf5a100 commit 23191bb

File tree

2 files changed

+75
-24
lines changed

2 files changed

+75
-24
lines changed

src/rabbit_env.erl

Lines changed: 40 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@
2424
context_to_code_path/1]).
2525

2626
-ifdef(TEST).
27-
-export([value_is_yes/1]).
27+
-export([parse_conf_env_file_output2/2,
28+
value_is_yes/1]).
2829
-endif.
2930

3031
-define(USED_ENV_VARS,
@@ -1608,11 +1609,12 @@ parse_conf_env_file_output(Context, _, []) ->
16081609
Context;
16091610
parse_conf_env_file_output(Context, Marker, [Marker | Lines]) ->
16101611
%% Found our marker, let's parse variables.
1611-
parse_conf_env_file_output1(Context, Lines, #{});
1612+
parse_conf_env_file_output1(Context, Lines);
16121613
parse_conf_env_file_output(Context, Marker, [_ | Lines]) ->
16131614
parse_conf_env_file_output(Context, Marker, Lines).
16141615

1615-
parse_conf_env_file_output1(Context, [], Vars) ->
1616+
parse_conf_env_file_output1(Context, Lines) ->
1617+
Vars = parse_conf_env_file_output2(Lines, #{}),
16161618
%% Re-export variables.
16171619
lists:foreach(
16181620
fun(Var) ->
@@ -1628,27 +1630,30 @@ parse_conf_env_file_output1(Context, [], Vars) ->
16281630
ok
16291631
end
16301632
end, lists:sort(maps:keys(Vars))),
1631-
Context;
1632-
parse_conf_env_file_output1(Context, [Line | Lines], Vars) ->
1633+
Context.
1634+
1635+
parse_conf_env_file_output2([], Vars) ->
1636+
Vars;
1637+
parse_conf_env_file_output2([Line | Lines], Vars) ->
16331638
SetXOutput = is_sh_set_x_output(Line),
16341639
ShFunction = is_sh_function(Line, Lines),
16351640
if
16361641
SetXOutput ->
1637-
parse_conf_env_file_output1(Context, Lines, Vars);
1642+
parse_conf_env_file_output2(Lines, Vars);
16381643
ShFunction ->
1639-
skip_sh_function(Context, Lines, Vars);
1644+
skip_sh_function(Lines, Vars);
16401645
true ->
16411646
case string:split(Line, "=") of
16421647
[Var, IncompleteValue] ->
1643-
{Value, Lines1} = parse_sh_literal(IncompleteValue, Lines),
1648+
{Value, Lines1} = parse_sh_literal(IncompleteValue, Lines, ""),
16441649
Vars1 = Vars#{Var => Value},
1645-
parse_conf_env_file_output1(Context, Lines1, Vars1);
1650+
parse_conf_env_file_output2(Lines1, Vars1);
16461651
_ ->
16471652
%% Parsing failed somehow.
16481653
rabbit_log_prelaunch:warning(
16491654
"Failed to parse $RABBITMQ_CONF_ENV_FILE output: ~p",
16501655
[Line]),
1651-
Context
1656+
#{}
16521657
end
16531658
end.
16541659

@@ -1662,16 +1667,18 @@ is_sh_function(Line, Lines) ->
16621667
andalso
16631668
re:run(hd(Lines), "^\\s*\\{\\s*$", [{capture, none}]) =:= match.
16641669

1665-
parse_sh_literal("'" ++ SingleQuoted, Lines) ->
1666-
parse_single_quoted_literal(SingleQuoted, Lines, "");
1667-
parse_sh_literal("$'" ++ DollarSingleQuoted, Lines) ->
1668-
parse_dollar_single_quoted_literal(DollarSingleQuoted, Lines, "");
1669-
parse_sh_literal(Unquoted, Lines) ->
1670-
{Unquoted, Lines}.
1670+
parse_sh_literal("'" ++ SingleQuoted, Lines, Literal) ->
1671+
parse_single_quoted_literal(SingleQuoted, Lines, Literal);
1672+
parse_sh_literal("\"" ++ DoubleQuoted, Lines, Literal) ->
1673+
parse_double_quoted_literal(DoubleQuoted, Lines, Literal);
1674+
parse_sh_literal("$'" ++ DollarSingleQuoted, Lines, Literal) ->
1675+
parse_dollar_single_quoted_literal(DollarSingleQuoted, Lines, Literal);
1676+
parse_sh_literal(Unquoted, Lines, Literal) ->
1677+
{lists:reverse(Literal) ++ Unquoted, Lines}.
16711678

1672-
parse_single_quoted_literal([$'], Lines, Literal) ->
1679+
parse_single_quoted_literal([$' | Rest], Lines, Literal) ->
16731680
%% We reached the closing single quote.
1674-
{lists:reverse(Literal), Lines};
1681+
parse_sh_literal(Rest, Lines, Literal);
16751682
parse_single_quoted_literal([], [Line | Lines], Literal) ->
16761683
%% We reached the end of line before finding the closing single
16771684
%% quote. The literal continues on the next line and includes that
@@ -1680,6 +1687,17 @@ parse_single_quoted_literal([], [Line | Lines], Literal) ->
16801687
parse_single_quoted_literal([C | Rest], Lines, Literal) ->
16811688
parse_single_quoted_literal(Rest, Lines, [C | Literal]).
16821689

1690+
parse_double_quoted_literal([$" | Rest], Lines, Literal) ->
1691+
%% We reached the closing double quote.
1692+
parse_sh_literal(Rest, Lines, Literal);
1693+
parse_double_quoted_literal([], [Line | Lines], Literal) ->
1694+
%% We reached the end of line before finding the closing double
1695+
%% quote. The literal continues on the next line and includes that
1696+
%% newline character.
1697+
parse_double_quoted_literal(Line, Lines, [$\n | Literal]);
1698+
parse_double_quoted_literal([C | Rest], Lines, Literal) ->
1699+
parse_double_quoted_literal(Rest, Lines, [C | Literal]).
1700+
16831701
parse_dollar_single_quoted_literal([$'], Lines, Literal) ->
16841702
%% We reached the closing single quote.
16851703
{lists:reverse(Literal), Lines};
@@ -1691,10 +1709,10 @@ parse_dollar_single_quoted_literal([], [Line | Lines], Literal) ->
16911709
parse_dollar_single_quoted_literal([C | Rest], Lines, Literal) ->
16921710
parse_dollar_single_quoted_literal(Rest, Lines, [C | Literal]).
16931711

1694-
skip_sh_function(Context, ["}" | Lines], Vars) ->
1695-
parse_conf_env_file_output1(Context, Lines, Vars);
1696-
skip_sh_function(Context, [_ | Lines], Vars) ->
1697-
skip_sh_function(Context, Lines, Vars).
1712+
skip_sh_function(["}" | Lines], Vars) ->
1713+
parse_conf_env_file_output2(Lines, Vars);
1714+
skip_sh_function([_ | Lines], Vars) ->
1715+
skip_sh_function(Lines, Vars).
16981716

16991717
%% -------------------------------------------------------------------
17001718
%% Helpers.

test/rabbit_env_SUITE.erl

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,8 @@
5454
check_value_is_yes/1,
5555
check_log_process_env/1,
5656
check_log_context/1,
57-
check_get_used_env_vars/1
57+
check_get_used_env_vars/1,
58+
check_parse_conf_env_file_output/1
5859
]).
5960

6061
all() ->
@@ -93,7 +94,8 @@ all() ->
9394
check_value_is_yes,
9495
check_log_process_env,
9596
check_log_context,
96-
check_get_used_env_vars
97+
check_get_used_env_vars,
98+
check_parse_conf_env_file_output
9799
].
98100

99101
suite() ->
@@ -1063,3 +1065,34 @@ get_default_nodename() ->
10631065
"rabbit@\\1",
10641066
[{return, list}]),
10651067
list_to_atom(NodeS).
1068+
1069+
check_parse_conf_env_file_output(_) ->
1070+
?assertEqual(
1071+
#{},
1072+
rabbit_env:parse_conf_env_file_output2(
1073+
[],
1074+
#{}
1075+
)),
1076+
?assertEqual(
1077+
#{"UNQUOTED" => "a",
1078+
"SINGLE_QUOTED" => "b",
1079+
"DOUBLE_QUOTED" => "c",
1080+
"SINGLE_DOLLAR" => "d"},
1081+
rabbit_env:parse_conf_env_file_output2(
1082+
["UNQUOTED=a",
1083+
"SINGLE_QUOTED='b'",
1084+
"DOUBLE_QUOTED=\"c\"",
1085+
"SINGLE_DOLLAR=$'d'"],
1086+
#{}
1087+
)),
1088+
?assertEqual(
1089+
#{"A" => "a",
1090+
"B" => "b",
1091+
"MULTI_LINE" => "\n'foobar'"},
1092+
rabbit_env:parse_conf_env_file_output2(
1093+
["A=a",
1094+
"MULTI_LINE='",
1095+
"'\"'\"'foobar'\"'\"",
1096+
"B=b"],
1097+
#{}
1098+
)).

0 commit comments

Comments
 (0)