blob: 68d0874d90c9326e7d44c30a5369fa8d3548a9c8 [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{
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();
Ion Agorria6722ea52024-01-05 09:22:12 +020056 ut_assert_console_end();
Francis Laniel91ec8702023-12-22 22:02:24 +010057
58 ut_asserteq(1, run_command("dollar_foo=bar quux\"", 0));
Ion Agorria6722ea52024-01-05 09:22:12 +020059 /* Next line contains error message */
Francis Laniel91ec8702023-12-22 22:02:24 +010060 ut_assert_skipline();
Ion Agorria6722ea52024-01-05 09:22:12 +020061 ut_assert_console_end();
Francis Laniel91ec8702023-12-22 22:02:24 +010062
63 ut_assertok(run_command("dollar_foo='bar \"quux'", 0));
64
65 ut_assertok(run_command("echo $dollar_foo", 0));
66 /*
67 * This one is buggy.
68 * ut_assert_nextline("bar \"quux");
69 * ut_assert_console_end();
70 *
71 * So, let's reset output:
72 */
73 console_record_reset_enable();
74
Francis Laniel0c0495c2023-12-22 22:02:37 +010075 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
76 /*
77 * Old parser returns an error because it waits for closing
78 * '\'', but this behavior is wrong as the '\'' is surrounded by
79 * '"', so no need to wait for a closing one.
80 */
81 ut_assertok(run_command("dollar_foo=\"bar 'quux\"", 0));
82
83 ut_assertok(run_command("echo $dollar_foo", 0));
84 ut_assert_nextline("bar 'quux");
85 ut_assert_console_end();
86 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
87 ut_asserteq(1, run_command("dollar_foo=\"bar 'quux\"", 0));
88 /* Next line contains error message */
89 ut_assert_skipline();
90 ut_assert_console_end();
91 }
Francis Laniel91ec8702023-12-22 22:02:24 +010092
93 ut_assertok(run_command("dollar_foo='bar quux'", 0));
94 ut_assertok(run_command("echo $dollar_foo", 0));
95 ut_assert_nextline("bar quux");
96 ut_assert_console_end();
97
Francis Laniel0c0495c2023-12-22 22:02:37 +010098 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
99 /* Reset local variable. */
100 ut_assertok(run_command("dollar_foo=", 0));
101 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
102 puts("Beware: this test set local variable dollar_foo and it cannot be unset!");
103 }
Francis Laniel91ec8702023-12-22 22:02:24 +0100104
105 return 0;
106}
107HUSH_TEST(hush_test_simple_dollar, 0);
108
109static int hush_test_env_dollar(struct unit_test_state *uts)
110{
111 env_set("env_foo", "bar");
112 console_record_reset_enable();
113
114 ut_assertok(run_command("echo $env_foo", 0));
115 ut_assert_nextline("bar");
116 ut_assert_console_end();
117
118 ut_assertok(run_command("echo ${env_foo}", 0));
119 ut_assert_nextline("bar");
120 ut_assert_console_end();
121
122 /* Environment variables have priority over local variable */
123 ut_assertok(run_command("env_foo=quux", 0));
124 ut_assertok(run_command("echo ${env_foo}", 0));
125 ut_assert_nextline("bar");
126 ut_assert_console_end();
127
128 /* Clean up setting the variable */
129 env_set("env_foo", NULL);
130
Francis Laniel0c0495c2023-12-22 22:02:37 +0100131 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
132 /* Reset local variable. */
133 ut_assertok(run_command("env_foo=", 0));
134 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
135 puts("Beware: this test set local variable env_foo and it cannot be unset!");
136 }
Francis Laniel91ec8702023-12-22 22:02:24 +0100137
138 return 0;
139}
140HUSH_TEST(hush_test_env_dollar, 0);
141
142static int hush_test_command_dollar(struct unit_test_state *uts)
143{
144 console_record_reset_enable();
145
146 ut_assertok(run_command("dollar_bar=\"echo bar\"", 0));
147
148 ut_assertok(run_command("$dollar_bar", 0));
149 ut_assert_nextline("bar");
150 ut_assert_console_end();
151
152 ut_assertok(run_command("${dollar_bar}", 0));
153 ut_assert_nextline("bar");
154 ut_assert_console_end();
155
156 ut_assertok(run_command("dollar_bar=\"echo\nbar\"", 0));
157
158 ut_assertok(run_command("$dollar_bar", 0));
159 ut_assert_nextline("bar");
160 ut_assert_console_end();
161
162 ut_assertok(run_command("dollar_bar='echo bar\n'", 0));
163
164 ut_assertok(run_command("$dollar_bar", 0));
165 ut_assert_nextline("bar");
166 ut_assert_console_end();
167
168 ut_assertok(run_command("dollar_bar='echo bar\\n'", 0));
169
170 ut_assertok(run_command("$dollar_bar", 0));
Francis Laniel0c0495c2023-12-22 22:02:37 +0100171
172 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
173 /*
174 * This difference seems to come from a bug solved in Busybox
175 * hush.
176 * Behavior of hush 2021 is coherent with bash and other shells.
177 */
178 ut_assert_nextline("bar\\n");
179 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
180 ut_assert_nextline("barn");
181 }
182
Francis Laniel91ec8702023-12-22 22:02:24 +0100183 ut_assert_console_end();
184
185 ut_assertok(run_command("dollar_bar='echo $bar'", 0));
186
187 ut_assertok(run_command("$dollar_bar", 0));
188 ut_assert_nextline("$bar");
189 ut_assert_console_end();
190
191 ut_assertok(run_command("dollar_quux=quux", 0));
192 ut_assertok(run_command("dollar_bar=\"echo $dollar_quux\"", 0));
193
194 ut_assertok(run_command("$dollar_bar", 0));
195 ut_assert_nextline("quux");
196 ut_assert_console_end();
197
Francis Laniel0c0495c2023-12-22 22:02:37 +0100198 if (gd->flags & GD_FLG_HUSH_MODERN_PARSER) {
199 /* Reset local variables. */
200 ut_assertok(run_command("dollar_bar=", 0));
201 ut_assertok(run_command("dollar_quux=", 0));
202 } else if (gd->flags & GD_FLG_HUSH_OLD_PARSER) {
203 puts("Beware: this test sets local variable dollar_bar and dollar_quux and they cannot be unset!");
204 }
Francis Laniel91ec8702023-12-22 22:02:24 +0100205
206 return 0;
207}
208HUSH_TEST(hush_test_command_dollar, 0);