blob: 91b097017c2a8fbf63b2f4bfac332d87d29bbe55 [file] [log] [blame]
Francis Laniel91ec8702023-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 Laniel91ec8702023-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 Laniel0c0495c2023-12-22 22:02:37 +010011#include <asm/global_data.h>
12
13DECLARE_GLOBAL_DATA_PTR;
Francis Laniel91ec8702023-12-22 22:02:24 +010014
15static int hush_test_simple_dollar(struct unit_test_state *uts)
16{
Francis Laniel91ec8702023-12-22 22:02:24 +010017 ut_assertok(run_command("echo $dollar_foo", 0));
18 ut_assert_nextline_empty();
19 ut_assert_console_end();
20
21 ut_assertok(run_command("echo ${dollar_foo}", 0));
22 ut_assert_nextline_empty();
23 ut_assert_console_end();
24
25 ut_assertok(run_command("dollar_foo=bar", 0));
26
27 ut_assertok(run_command("echo $dollar_foo", 0));
28 ut_assert_nextline("bar");
29 ut_assert_console_end();
30
31 ut_assertok(run_command("echo ${dollar_foo}", 0));
32 ut_assert_nextline("bar");
33 ut_assert_console_end();
34
35 ut_assertok(run_command("dollar_foo=\\$bar", 0));
36
37 ut_assertok(run_command("echo $dollar_foo", 0));
38 ut_assert_nextline("$bar");
39 ut_assert_console_end();
40
41 ut_assertok(run_command("dollar_foo='$bar'", 0));
42
43 ut_assertok(run_command("echo $dollar_foo", 0));
44 ut_assert_nextline("$bar");
45 ut_assert_console_end();
46
47 ut_asserteq(1, run_command("dollar_foo=bar quux", 0));
48 /* Next line contains error message */
49 ut_assert_skipline();
50 ut_assert_console_end();
51
52 ut_asserteq(1, run_command("dollar_foo='bar quux", 0));
53 /* Next line contains error message */
54 ut_assert_skipline();
Tom Rinida3ae1f2024-01-18 11:38:25 -050055
56 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
57 /*
58 * For some strange reasons, the console is not empty after
59 * running above command.
60 * So, we reset it to not have side effects for other tests.
61 */
62 console_record_reset_enable();
63 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
64 ut_assert_console_end();
65 }
Francis Laniel91ec8702023-12-22 22:02:24 +010066
67 ut_asserteq(1, run_command("dollar_foo=bar quux\"", 0));
Tom Rinida3ae1f2024-01-18 11:38:25 -050068 /* Two next lines contain error message */
Francis Laniel91ec8702023-12-22 22:02:24 +010069 ut_assert_skipline();
Tom Rinida3ae1f2024-01-18 11:38:25 -050070 ut_assert_skipline();
71
72 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
73 /* See above comments. */
74 console_record_reset_enable();
75 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
76 ut_assert_console_end();
77 }
Francis Laniel91ec8702023-12-22 22:02:24 +010078
79 ut_assertok(run_command("dollar_foo='bar \"quux'", 0));
80
81 ut_assertok(run_command("echo $dollar_foo", 0));
82 /*
83 * This one is buggy.
84 * ut_assert_nextline("bar \"quux");
85 * ut_assert_console_end();
86 *
87 * So, let's reset output:
88 */
89 console_record_reset_enable();
90
Francis Laniel0c0495c2023-12-22 22:02:37 +010091 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
92 /*
93 * Old parser returns an error because it waits for closing
94 * '\'', but this behavior is wrong as the '\'' is surrounded by
95 * '"', so no need to wait for a closing one.
96 */
97 ut_assertok(run_command("dollar_foo=\"bar 'quux\"", 0));
98
99 ut_assertok(run_command("echo $dollar_foo", 0));
100 ut_assert_nextline("bar 'quux");
101 ut_assert_console_end();
102 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
103 ut_asserteq(1, run_command("dollar_foo=\"bar 'quux\"", 0));
104 /* Next line contains error message */
105 ut_assert_skipline();
106 ut_assert_console_end();
107 }
Francis Laniel91ec8702023-12-22 22:02:24 +0100108
109 ut_assertok(run_command("dollar_foo='bar quux'", 0));
110 ut_assertok(run_command("echo $dollar_foo", 0));
111 ut_assert_nextline("bar quux");
112 ut_assert_console_end();
113
Francis Laniel0c0495c2023-12-22 22:02:37 +0100114 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
115 /* Reset local variable. */
116 ut_assertok(run_command("dollar_foo=", 0));
117 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
118 puts("Beware: this test set local variable dollar_foo and it cannot be unset!");
119 }
Francis Laniel91ec8702023-12-22 22:02:24 +0100120
121 return 0;
122}
Simon Glassf8dc3792024-08-22 07:58:00 -0600123HUSH_TEST(hush_test_simple_dollar, UTF_CONSOLE);
Francis Laniel91ec8702023-12-22 22:02:24 +0100124
125static int hush_test_env_dollar(struct unit_test_state *uts)
126{
127 env_set("env_foo", "bar");
Francis Laniel91ec8702023-12-22 22:02:24 +0100128
129 ut_assertok(run_command("echo $env_foo", 0));
130 ut_assert_nextline("bar");
131 ut_assert_console_end();
132
133 ut_assertok(run_command("echo ${env_foo}", 0));
134 ut_assert_nextline("bar");
135 ut_assert_console_end();
136
137 /* Environment variables have priority over local variable */
138 ut_assertok(run_command("env_foo=quux", 0));
139 ut_assertok(run_command("echo ${env_foo}", 0));
140 ut_assert_nextline("bar");
141 ut_assert_console_end();
142
143 /* Clean up setting the variable */
144 env_set("env_foo", NULL);
145
Francis Laniel0c0495c2023-12-22 22:02:37 +0100146 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
147 /* Reset local variable. */
148 ut_assertok(run_command("env_foo=", 0));
149 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
150 puts("Beware: this test set local variable env_foo and it cannot be unset!");
151 }
Francis Laniel91ec8702023-12-22 22:02:24 +0100152
153 return 0;
154}
Simon Glassf8dc3792024-08-22 07:58:00 -0600155HUSH_TEST(hush_test_env_dollar, UTF_CONSOLE);
Francis Laniel91ec8702023-12-22 22:02:24 +0100156
157static int hush_test_command_dollar(struct unit_test_state *uts)
158{
Francis Laniel91ec8702023-12-22 22:02:24 +0100159 ut_assertok(run_command("dollar_bar=\"echo bar\"", 0));
160
161 ut_assertok(run_command("$dollar_bar", 0));
162 ut_assert_nextline("bar");
163 ut_assert_console_end();
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=\"echo\nbar\"", 0));
170
171 ut_assertok(run_command("$dollar_bar", 0));
172 ut_assert_nextline("bar");
173 ut_assert_console_end();
174
175 ut_assertok(run_command("dollar_bar='echo bar\n'", 0));
176
177 ut_assertok(run_command("$dollar_bar", 0));
178 ut_assert_nextline("bar");
179 ut_assert_console_end();
180
181 ut_assertok(run_command("dollar_bar='echo bar\\n'", 0));
182
183 ut_assertok(run_command("$dollar_bar", 0));
Francis Laniel0c0495c2023-12-22 22:02:37 +0100184
185 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
186 /*
187 * This difference seems to come from a bug solved in Busybox
188 * hush.
189 * Behavior of hush 2021 is coherent with bash and other shells.
190 */
191 ut_assert_nextline("bar\\n");
192 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
193 ut_assert_nextline("barn");
194 }
195
Francis Laniel91ec8702023-12-22 22:02:24 +0100196 ut_assert_console_end();
197
198 ut_assertok(run_command("dollar_bar='echo $bar'", 0));
199
200 ut_assertok(run_command("$dollar_bar", 0));
201 ut_assert_nextline("$bar");
202 ut_assert_console_end();
203
204 ut_assertok(run_command("dollar_quux=quux", 0));
205 ut_assertok(run_command("dollar_bar=\"echo $dollar_quux\"", 0));
206
207 ut_assertok(run_command("$dollar_bar", 0));
208 ut_assert_nextline("quux");
209 ut_assert_console_end();
210
Francis Laniel0c0495c2023-12-22 22:02:37 +0100211 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
212 /* Reset local variables. */
213 ut_assertok(run_command("dollar_bar=", 0));
214 ut_assertok(run_command("dollar_quux=", 0));
215 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
216 puts("Beware: this test sets local variable dollar_bar and dollar_quux and they cannot be unset!");
217 }
Francis Laniel91ec8702023-12-22 22:02:24 +0100218
219 return 0;
220}
Simon Glassf8dc3792024-08-22 07:58:00 -0600221HUSH_TEST(hush_test_command_dollar, UTF_CONSOLE);