]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/test/test-env-util.c
Merge pull request #5449 from keszybz/blkd-error-handling
[thirdparty/systemd.git] / src / test / test-env-util.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5 Copyright 2016 Zbigniew Jędrzejewski-Szmek
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19 ***/
20
21 #include <string.h>
22
23 #include "env-util.h"
24 #include "string-util.h"
25 #include "strv.h"
26 #include "util.h"
27
28 static void test_strv_env_delete(void) {
29 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
30
31 a = strv_new("FOO=BAR", "WALDO=WALDO", "WALDO=", "PIEP", "SCHLUMPF=SMURF", NULL);
32 assert_se(a);
33
34 b = strv_new("PIEP", "FOO", NULL);
35 assert_se(b);
36
37 c = strv_new("SCHLUMPF", NULL);
38 assert_se(c);
39
40 d = strv_env_delete(a, 2, b, c);
41 assert_se(d);
42
43 assert_se(streq(d[0], "WALDO=WALDO"));
44 assert_se(streq(d[1], "WALDO="));
45 assert_se(strv_length(d) == 2);
46 }
47
48 static void test_strv_env_get(void) {
49 char **l;
50
51 l = STRV_MAKE("ONE_OR_TWO=1", "THREE=3", "ONE_OR_TWO=2", "FOUR=4");
52
53 assert_se(streq(strv_env_get(l, "ONE_OR_TWO"), "2"));
54 assert_se(streq(strv_env_get(l, "THREE"), "3"));
55 assert_se(streq(strv_env_get(l, "FOUR"), "4"));
56 }
57
58 static void test_strv_env_unset(void) {
59 _cleanup_strv_free_ char **l = NULL;
60
61 l = strv_new("PIEP", "SCHLUMPF=SMURFF", "NANANANA=YES", NULL);
62 assert_se(l);
63
64 assert_se(strv_env_unset(l, "SCHLUMPF") == l);
65
66 assert_se(streq(l[0], "PIEP"));
67 assert_se(streq(l[1], "NANANANA=YES"));
68 assert_se(strv_length(l) == 2);
69 }
70
71 static void test_strv_env_set(void) {
72 _cleanup_strv_free_ char **l = NULL, **r = NULL;
73
74 l = strv_new("PIEP", "SCHLUMPF=SMURFF", "NANANANA=YES", NULL);
75 assert_se(l);
76
77 r = strv_env_set(l, "WALDO=WALDO");
78 assert_se(r);
79
80 assert_se(streq(r[0], "PIEP"));
81 assert_se(streq(r[1], "SCHLUMPF=SMURFF"));
82 assert_se(streq(r[2], "NANANANA=YES"));
83 assert_se(streq(r[3], "WALDO=WALDO"));
84 assert_se(strv_length(r) == 4);
85 }
86
87 static void test_strv_env_merge(void) {
88 _cleanup_strv_free_ char **a = NULL, **b = NULL, **r = NULL;
89
90 a = strv_new("FOO=BAR", "WALDO=WALDO", "WALDO=", "PIEP", "SCHLUMPF=SMURF", NULL);
91 assert_se(a);
92
93 b = strv_new("FOO=KKK", "FOO=", "PIEP=", "SCHLUMPF=SMURFF", "NANANANA=YES", NULL);
94 assert_se(b);
95
96 r = strv_env_merge(2, a, b);
97 assert_se(r);
98 assert_se(streq(r[0], "FOO="));
99 assert_se(streq(r[1], "WALDO="));
100 assert_se(streq(r[2], "PIEP"));
101 assert_se(streq(r[3], "SCHLUMPF=SMURFF"));
102 assert_se(streq(r[4], "PIEP="));
103 assert_se(streq(r[5], "NANANANA=YES"));
104 assert_se(strv_length(r) == 6);
105
106 assert_se(strv_env_clean(r) == r);
107 assert_se(streq(r[0], "FOO="));
108 assert_se(streq(r[1], "WALDO="));
109 assert_se(streq(r[2], "SCHLUMPF=SMURFF"));
110 assert_se(streq(r[3], "PIEP="));
111 assert_se(streq(r[4], "NANANANA=YES"));
112 assert_se(strv_length(r) == 5);
113 }
114
115 static void test_env_strv_get_n(void) {
116 const char *_env[] = {
117 "FOO=NO NO NO",
118 "FOO=BAR BAR",
119 "BAR=waldo",
120 "PATH=unset",
121 NULL
122 };
123 char **env = (char**) _env;
124
125 assert_se(streq(strv_env_get_n(env, "FOO__", 3, 0), "BAR BAR"));
126 assert_se(streq(strv_env_get_n(env, "FOO__", 3, REPLACE_ENV_USE_ENVIRONMENT), "BAR BAR"));
127 assert_se(streq(strv_env_get_n(env, "FOO", 3, 0), "BAR BAR"));
128 assert_se(streq(strv_env_get_n(env, "FOO", 3, REPLACE_ENV_USE_ENVIRONMENT), "BAR BAR"));
129
130 assert_se(streq(strv_env_get_n(env, "PATH__", 4, 0), "unset"));
131 assert_se(streq(strv_env_get_n(env, "PATH", 4, 0), "unset"));
132 assert_se(streq(strv_env_get_n(env, "PATH__", 4, REPLACE_ENV_USE_ENVIRONMENT), "unset"));
133 assert_se(streq(strv_env_get_n(env, "PATH", 4, REPLACE_ENV_USE_ENVIRONMENT), "unset"));
134
135 env[3] = NULL; /* kill our $PATH */
136
137 assert_se(!strv_env_get_n(env, "PATH__", 4, 0));
138 assert_se(!strv_env_get_n(env, "PATH", 4, 0));
139 assert_se(streq(strv_env_get_n(env, "PATH__", 4, REPLACE_ENV_USE_ENVIRONMENT),
140 getenv("PATH")));
141 assert_se(streq(strv_env_get_n(env, "PATH", 4, REPLACE_ENV_USE_ENVIRONMENT),
142 getenv("PATH")));
143 }
144
145 static void test_replace_env(bool braceless) {
146 const char *env[] = {
147 "FOO=BAR BAR",
148 "BAR=waldo",
149 NULL
150 };
151 _cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL;
152 unsigned flags = REPLACE_ENV_ALLOW_BRACELESS*braceless;
153
154 t = replace_env("FOO=$FOO=${FOO}", (char**) env, flags);
155 assert_se(streq(t, braceless ? "FOO=BAR BAR=BAR BAR" : "FOO=$FOO=BAR BAR"));
156
157 s = replace_env("BAR=$BAR=${BAR}", (char**) env, flags);
158 assert_se(streq(s, braceless ? "BAR=waldo=waldo" : "BAR=$BAR=waldo"));
159
160 q = replace_env("BARBAR=$BARBAR=${BARBAR}", (char**) env, flags);
161 assert_se(streq(q, braceless ? "BARBAR==" : "BARBAR=$BARBAR="));
162
163 r = replace_env("BAR=$BAR$BAR${BAR}${BAR}", (char**) env, flags);
164 assert_se(streq(r, braceless ? "BAR=waldowaldowaldowaldo" : "BAR=$BAR$BARwaldowaldo"));
165
166 p = replace_env("${BAR}$BAR$BAR", (char**) env, flags);
167 assert_se(streq(p, braceless ? "waldowaldowaldo" : "waldo$BAR$BAR"));
168 }
169
170 static void test_replace_env2(bool extended) {
171 const char *env[] = {
172 "FOO=foo",
173 "BAR=bar",
174 NULL
175 };
176 _cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL, *x = NULL;
177 unsigned flags = REPLACE_ENV_ALLOW_EXTENDED*extended;
178
179 t = replace_env("FOO=${FOO:-${BAR}}", (char**) env, flags);
180 assert_se(streq(t, extended ? "FOO=foo" : "FOO=${FOO:-bar}"));
181
182 s = replace_env("BAR=${XXX:-${BAR}}", (char**) env, flags);
183 assert_se(streq(s, extended ? "BAR=bar" : "BAR=${XXX:-bar}"));
184
185 q = replace_env("XXX=${XXX:+${BAR}}", (char**) env, flags);
186 assert_se(streq(q, extended ? "XXX=" : "XXX=${XXX:+bar}"));
187
188 r = replace_env("FOO=${FOO:+${BAR}}", (char**) env, flags);
189 assert_se(streq(r, extended ? "FOO=bar" : "FOO=${FOO:+bar}"));
190
191 p = replace_env("FOO=${FOO:-${BAR}post}", (char**) env, flags);
192 assert_se(streq(p, extended ? "FOO=foo" : "FOO=${FOO:-barpost}"));
193
194 x = replace_env("XXX=${XXX:+${BAR}post}", (char**) env, flags);
195 assert_se(streq(x, extended ? "XXX=" : "XXX=${XXX:+barpost}"));
196 }
197
198 static void test_replace_env_argv(void) {
199 const char *env[] = {
200 "FOO=BAR BAR",
201 "BAR=waldo",
202 NULL
203 };
204 const char *line[] = {
205 "FOO$FOO",
206 "FOO$FOOFOO",
207 "FOO${FOO}$FOO",
208 "FOO${FOO}",
209 "${FOO}",
210 "$FOO",
211 "$FOO$FOO",
212 "${FOO}${BAR}",
213 "${FOO",
214 "FOO$$${FOO}",
215 "$$FOO${FOO}",
216 "${FOO:-${BAR}}",
217 "${QUUX:-${FOO}}",
218 "${FOO:+${BAR}}",
219 "${QUUX:+${BAR}}",
220 "${FOO:+|${BAR}|}}",
221 "${FOO:+|${BAR}{|}",
222 NULL
223 };
224 _cleanup_strv_free_ char **r = NULL;
225
226 r = replace_env_argv((char**) line, (char**) env);
227 assert_se(r);
228 assert_se(streq(r[0], "FOO$FOO"));
229 assert_se(streq(r[1], "FOO$FOOFOO"));
230 assert_se(streq(r[2], "FOOBAR BAR$FOO"));
231 assert_se(streq(r[3], "FOOBAR BAR"));
232 assert_se(streq(r[4], "BAR BAR"));
233 assert_se(streq(r[5], "BAR"));
234 assert_se(streq(r[6], "BAR"));
235 assert_se(streq(r[7], "BAR BARwaldo"));
236 assert_se(streq(r[8], "${FOO"));
237 assert_se(streq(r[9], "FOO$BAR BAR"));
238 assert_se(streq(r[10], "$FOOBAR BAR"));
239 assert_se(streq(r[11], "${FOO:-waldo}"));
240 assert_se(streq(r[12], "${QUUX:-BAR BAR}"));
241 assert_se(streq(r[13], "${FOO:+waldo}"));
242 assert_se(streq(r[14], "${QUUX:+waldo}"));
243 assert_se(streq(r[15], "${FOO:+|waldo|}}"));
244 assert_se(streq(r[16], "${FOO:+|waldo{|}"));
245 assert_se(strv_length(r) == 17);
246 }
247
248 static void test_env_clean(void) {
249 _cleanup_strv_free_ char **e;
250
251 e = strv_new("FOOBAR=WALDO",
252 "FOOBAR=WALDO",
253 "FOOBAR",
254 "F",
255 "X=",
256 "F=F",
257 "=",
258 "=F",
259 "",
260 "0000=000",
261 "äöüß=abcd",
262 "abcd=äöüß",
263 "xyz\n=xyz",
264 "xyz=xyz\n",
265 "another=one",
266 "another=final one",
267 NULL);
268 assert_se(e);
269 assert_se(!strv_env_is_valid(e));
270 assert_se(strv_env_clean(e) == e);
271 assert_se(strv_env_is_valid(e));
272
273 assert_se(streq(e[0], "FOOBAR=WALDO"));
274 assert_se(streq(e[1], "X="));
275 assert_se(streq(e[2], "F=F"));
276 assert_se(streq(e[3], "abcd=äöüß"));
277 assert_se(streq(e[4], "another=final one"));
278 assert_se(e[5] == NULL);
279 }
280
281 static void test_env_name_is_valid(void) {
282 assert_se(env_name_is_valid("test"));
283
284 assert_se(!env_name_is_valid(NULL));
285 assert_se(!env_name_is_valid(""));
286 assert_se(!env_name_is_valid("xxx\a"));
287 assert_se(!env_name_is_valid("xxx\007b"));
288 assert_se(!env_name_is_valid("\007\009"));
289 assert_se(!env_name_is_valid("5_starting_with_a_number_is_wrong"));
290 assert_se(!env_name_is_valid("#¤%&?_only_numbers_letters_and_underscore_allowed"));
291 }
292
293 static void test_env_value_is_valid(void) {
294 assert_se(env_value_is_valid(""));
295 assert_se(env_value_is_valid("głąb kapuściany"));
296 assert_se(env_value_is_valid("printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
297 }
298
299 static void test_env_assignment_is_valid(void) {
300 assert_se(env_assignment_is_valid("a="));
301 assert_se(env_assignment_is_valid("b=głąb kapuściany"));
302 assert_se(env_assignment_is_valid("c=\\007\\009\\011"));
303 assert_se(env_assignment_is_valid("e=printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
304
305 assert_se(!env_assignment_is_valid("="));
306 assert_se(!env_assignment_is_valid("a b="));
307 assert_se(!env_assignment_is_valid("a ="));
308 assert_se(!env_assignment_is_valid(" b="));
309 /* no dots or dashes: http://tldp.org/LDP/abs/html/gotchas.html */
310 assert_se(!env_assignment_is_valid("a.b="));
311 assert_se(!env_assignment_is_valid("a-b="));
312 assert_se(!env_assignment_is_valid("\007=głąb kapuściany"));
313 assert_se(!env_assignment_is_valid("c\009=\007\009\011"));
314 assert_se(!env_assignment_is_valid("głąb=printf \"\x1b]0;<mock-chroot>\x07<mock-chroot>\""));
315 }
316
317 int main(int argc, char *argv[]) {
318 test_strv_env_delete();
319 test_strv_env_get();
320 test_strv_env_unset();
321 test_strv_env_set();
322 test_strv_env_merge();
323 test_env_strv_get_n();
324 test_replace_env(false);
325 test_replace_env(true);
326 test_replace_env2(false);
327 test_replace_env2(true);
328 test_replace_env_argv();
329 test_env_clean();
330 test_env_name_is_valid();
331 test_env_value_is_valid();
332 test_env_assignment_is_valid();
333
334 return 0;
335 }