blob: 4caa07c192aac2ff2c0340013855af63c7705489 [file] [log] [blame]
Francis Laniel261d29e2023-12-22 22:02:24 +01001// SPDX-License-Identifier: GPL-2.0
2/*
3 * (C) Copyright 2021
4 * Francis Laniel, Amarula Solutions, francis.laniel@amarulasolutions.com
5 */
6
Francis Laniel261d29e2023-12-22 22:02:24 +01007#include <command.h>
8#include <env_attr.h>
9#include <test/hush.h>
10#include <test/ut.h>
Francis Laniel410e78d2023-12-22 22:02:37 +010011#include <asm/global_data.h>
12
13DECLARE_GLOBAL_DATA_PTR;
Francis Laniel261d29e2023-12-22 22:02:24 +010014
15static int hush_test_simple_dollar(struct unit_test_state *uts)
16{
17 console_record_reset_enable();
18 ut_assertok(run_command("echo $dollar_foo", 0));
19 ut_assert_nextline_empty();
20 ut_assert_console_end();
21
22 ut_assertok(run_command("echo ${dollar_foo}", 0));
23 ut_assert_nextline_empty();
24 ut_assert_console_end();
25
26 ut_assertok(run_command("dollar_foo=bar", 0));
27
28 ut_assertok(run_command("echo $dollar_foo", 0));
29 ut_assert_nextline("bar");
30 ut_assert_console_end();
31
32 ut_assertok(run_command("echo ${dollar_foo}", 0));
33 ut_assert_nextline("bar");
34 ut_assert_console_end();
35
36 ut_assertok(run_command("dollar_foo=\\$bar", 0));
37
38 ut_assertok(run_command("echo $dollar_foo", 0));
39 ut_assert_nextline("$bar");
40 ut_assert_console_end();
41
42 ut_assertok(run_command("dollar_foo='$bar'", 0));
43
44 ut_assertok(run_command("echo $dollar_foo", 0));
45 ut_assert_nextline("$bar");
46 ut_assert_console_end();
47
48 ut_asserteq(1, run_command("dollar_foo=bar quux", 0));
49 /* Next line contains error message */
50 ut_assert_skipline();
51 ut_assert_console_end();
52
53 ut_asserteq(1, run_command("dollar_foo='bar quux", 0));
54 /* Next line contains error message */
55 ut_assert_skipline();
Tom Rinif7cca7c2024-01-18 11:38:25 -050056
57 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
58 /*
59 * For some strange reasons, the console is not empty after
60 * running above command.
61 * So, we reset it to not have side effects for other tests.
62 */
63 console_record_reset_enable();
64 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
65 ut_assert_console_end();
66 }
Francis Laniel261d29e2023-12-22 22:02:24 +010067
68 ut_asserteq(1, run_command("dollar_foo=bar quux\"", 0));
Tom Rinif7cca7c2024-01-18 11:38:25 -050069 /* Two next lines contain error message */
Francis Laniel261d29e2023-12-22 22:02:24 +010070 ut_assert_skipline();
Tom Rinif7cca7c2024-01-18 11:38:25 -050071 ut_assert_skipline();
72
73 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
74 /* See above comments. */
75 console_record_reset_enable();
76 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
77 ut_assert_console_end();
78 }
Francis Laniel261d29e2023-12-22 22:02:24 +010079
80 ut_assertok(run_command("dollar_foo='bar \"quux'", 0));
81
82 ut_assertok(run_command("echo $dollar_foo", 0));
83 /*
84 * This one is buggy.
85 * ut_assert_nextline("bar \"quux");
86 * ut_assert_console_end();
87 *
88 * So, let's reset output:
89 */
90 console_record_reset_enable();
91
Francis Laniel410e78d2023-12-22 22:02:37 +010092 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
93 /*
94 * Old parser returns an error because it waits for closing
95 * '\'', but this behavior is wrong as the '\'' is surrounded by
96 * '"', so no need to wait for a closing one.
97 */
98 ut_assertok(run_command("dollar_foo=\"bar 'quux\"", 0));
99
100 ut_assertok(run_command("echo $dollar_foo", 0));
101 ut_assert_nextline("bar 'quux");
102 ut_assert_console_end();
103 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
104 ut_asserteq(1, run_command("dollar_foo=\"bar 'quux\"", 0));
105 /* Next line contains error message */
106 ut_assert_skipline();
107 ut_assert_console_end();
108 }
Francis Laniel261d29e2023-12-22 22:02:24 +0100109
110 ut_assertok(run_command("dollar_foo='bar quux'", 0));
111 ut_assertok(run_command("echo $dollar_foo", 0));
112 ut_assert_nextline("bar quux");
113 ut_assert_console_end();
114
Francis Laniel410e78d2023-12-22 22:02:37 +0100115 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
116 /* Reset local variable. */
117 ut_assertok(run_command("dollar_foo=", 0));
118 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
119 puts("Beware: this test set local variable dollar_foo and it cannot be unset!");
120 }
Francis Laniel261d29e2023-12-22 22:02:24 +0100121
122 return 0;
123}
124HUSH_TEST(hush_test_simple_dollar, 0);
125
126static int hush_test_env_dollar(struct unit_test_state *uts)
127{
128 env_set("env_foo", "bar");
129 console_record_reset_enable();
130
131 ut_assertok(run_command("echo $env_foo", 0));
132 ut_assert_nextline("bar");
133 ut_assert_console_end();
134
135 ut_assertok(run_command("echo ${env_foo}", 0));
136 ut_assert_nextline("bar");
137 ut_assert_console_end();
138
139 /* Environment variables have priority over local variable */
140 ut_assertok(run_command("env_foo=quux", 0));
141 ut_assertok(run_command("echo ${env_foo}", 0));
142 ut_assert_nextline("bar");
143 ut_assert_console_end();
144
145 /* Clean up setting the variable */
146 env_set("env_foo", NULL);
147
Francis Laniel410e78d2023-12-22 22:02:37 +0100148 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
149 /* Reset local variable. */
150 ut_assertok(run_command("env_foo=", 0));
151 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
152 puts("Beware: this test set local variable env_foo and it cannot be unset!");
153 }
Francis Laniel261d29e2023-12-22 22:02:24 +0100154
155 return 0;
156}
157HUSH_TEST(hush_test_env_dollar, 0);
158
159static int hush_test_command_dollar(struct unit_test_state *uts)
160{
161 console_record_reset_enable();
162
163 ut_assertok(run_command("dollar_bar=\"echo bar\"", 0));
164
165 ut_assertok(run_command("$dollar_bar", 0));
166 ut_assert_nextline("bar");
167 ut_assert_console_end();
168
169 ut_assertok(run_command("${dollar_bar}", 0));
170 ut_assert_nextline("bar");
171 ut_assert_console_end();
172
173 ut_assertok(run_command("dollar_bar=\"echo\nbar\"", 0));
174
175 ut_assertok(run_command("$dollar_bar", 0));
176 ut_assert_nextline("bar");
177 ut_assert_console_end();
178
179 ut_assertok(run_command("dollar_bar='echo bar\n'", 0));
180
181 ut_assertok(run_command("$dollar_bar", 0));
182 ut_assert_nextline("bar");
183 ut_assert_console_end();
184
185 ut_assertok(run_command("dollar_bar='echo bar\\n'", 0));
186
187 ut_assertok(run_command("$dollar_bar", 0));
Francis Laniel410e78d2023-12-22 22:02:37 +0100188
189 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
190 /*
191 * This difference seems to come from a bug solved in Busybox
192 * hush.
193 * Behavior of hush 2021 is coherent with bash and other shells.
194 */
195 ut_assert_nextline("bar\\n");
196 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
197 ut_assert_nextline("barn");
198 }
199
Francis Laniel261d29e2023-12-22 22:02:24 +0100200 ut_assert_console_end();
201
202 ut_assertok(run_command("dollar_bar='echo $bar'", 0));
203
204 ut_assertok(run_command("$dollar_bar", 0));
205 ut_assert_nextline("$bar");
206 ut_assert_console_end();
207
208 ut_assertok(run_command("dollar_quux=quux", 0));
209 ut_assertok(run_command("dollar_bar=\"echo $dollar_quux\"", 0));
210
211 ut_assertok(run_command("$dollar_bar", 0));
212 ut_assert_nextline("quux");
213 ut_assert_console_end();
214
Francis Laniel410e78d2023-12-22 22:02:37 +0100215 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
216 /* Reset local variables. */
217 ut_assertok(run_command("dollar_bar=", 0));
218 ut_assertok(run_command("dollar_quux=", 0));
219 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
220 puts("Beware: this test sets local variable dollar_bar and dollar_quux and they cannot be unset!");
221 }
Francis Laniel261d29e2023-12-22 22:02:24 +0100222
223 return 0;
224}
225HUSH_TEST(hush_test_command_dollar, 0);