]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-env-util.c
basic/include: replace _Static_assert() with static_assert()
[thirdparty/systemd.git] / src / test / test-env-util.c
CommitLineData
db9ecf05 1/* SPDX-License-Identifier: LGPL-2.1-or-later */
c24eb49e 2
fa34123c 3#include <stdlib.h>
4f18ff2e
YW
4#include <unistd.h>
5
4d1a6904 6#include "env-util.h"
cfd1c6e2
YW
7#include "parse-util.h"
8#include "process-util.h"
07630cea 9#include "strv.h"
2824374f 10#include "tests.h"
c24eb49e 11
4f7452a8 12TEST(strv_env_delete) {
940bd473
TA
13 _cleanup_strv_free_ char **a = NULL, **b = NULL, **c = NULL, **d = NULL;
14
bea1a013 15 a = strv_new("FOO=BAR", "WALDO=WALDO", "WALDO=", "PIEP", "SCHLUMPF=SMURF");
9b5d6bd9
LP
16 assert_se(a);
17
bea1a013 18 b = strv_new("PIEP", "FOO");
9b5d6bd9
LP
19 assert_se(b);
20
bea1a013 21 c = strv_new("SCHLUMPF");
9b5d6bd9 22 assert_se(c);
940bd473
TA
23
24 d = strv_env_delete(a, 2, b, c);
9b5d6bd9 25 assert_se(d);
940bd473 26
c79e88b3
IK
27 ASSERT_STREQ(d[0], "WALDO=WALDO");
28 ASSERT_STREQ(d[1], "WALDO=");
9b5d6bd9 29 assert_se(strv_length(d) == 2);
940bd473
TA
30}
31
4f7452a8 32TEST(strv_env_get) {
0b345642 33 char **l = STRV_MAKE("ONE_OR_TWO=1", "THREE=3", "ONE_OR_TWO=2", "FOUR=4");
6162512c 34
c79e88b3
IK
35 ASSERT_STREQ(strv_env_get(l, "ONE_OR_TWO"), "2");
36 ASSERT_STREQ(strv_env_get(l, "THREE"), "3");
37 ASSERT_STREQ(strv_env_get(l, "FOUR"), "4");
6162512c
RS
38}
39
4f7452a8 40TEST(strv_env_pairs_get) {
42e6a77b
LB
41 char **l = STRV_MAKE("ONE_OR_TWO", "1", "THREE", "3", "ONE_OR_TWO", "2", "FOUR", "4", "FIVE", "5", "SIX", "FIVE", "SEVEN", "7");
42
c79e88b3
IK
43 ASSERT_STREQ(strv_env_pairs_get(l, "ONE_OR_TWO"), "2");
44 ASSERT_STREQ(strv_env_pairs_get(l, "THREE"), "3");
45 ASSERT_STREQ(strv_env_pairs_get(l, "FOUR"), "4");
46 ASSERT_STREQ(strv_env_pairs_get(l, "FIVE"), "5");
42e6a77b
LB
47}
48
4f7452a8 49TEST(strv_env_unset) {
940bd473
TA
50 _cleanup_strv_free_ char **l = NULL;
51
bea1a013 52 l = strv_new("PIEP", "SCHLUMPF=SMURFF", "NANANANA=YES");
9b5d6bd9 53 assert_se(l);
940bd473 54
9b5d6bd9 55 assert_se(strv_env_unset(l, "SCHLUMPF") == l);
940bd473 56
c79e88b3
IK
57 ASSERT_STREQ(l[0], "PIEP");
58 ASSERT_STREQ(l[1], "NANANANA=YES");
9b5d6bd9 59 assert_se(strv_length(l) == 2);
940bd473
TA
60}
61
4f7452a8 62TEST(strv_env_merge) {
43cadb64
ZJS
63 char **a = STRV_MAKE("FOO=BAR", "WALDO=WALDO", "WALDO=", "PIEP", "SCHLUMPF=SMURF", "EQ===");
64 char **b = STRV_MAKE("FOO=KKK", "FOO=", "PIEP=", "SCHLUMPF=SMURFF", "NANANANA=YES");
1f28b2de 65
43cadb64 66 _cleanup_strv_free_ char **r = strv_env_merge(NULL, a, NULL, b, NULL, a, b, b, NULL);
9b5d6bd9 67 assert_se(r);
c79e88b3
IK
68 ASSERT_STREQ(r[0], "FOO=");
69 ASSERT_STREQ(r[1], "WALDO=");
70 ASSERT_STREQ(r[2], "PIEP");
71 ASSERT_STREQ(r[3], "SCHLUMPF=SMURFF");
72 ASSERT_STREQ(r[4], "EQ===");
73 ASSERT_STREQ(r[5], "PIEP=");
74 ASSERT_STREQ(r[6], "NANANANA=YES");
43cadb64 75 assert_se(strv_length(r) == 7);
9b5d6bd9
LP
76
77 assert_se(strv_env_clean(r) == r);
c79e88b3
IK
78 ASSERT_STREQ(r[0], "FOO=");
79 ASSERT_STREQ(r[1], "WALDO=");
80 ASSERT_STREQ(r[2], "SCHLUMPF=SMURFF");
81 ASSERT_STREQ(r[3], "EQ===");
82 ASSERT_STREQ(r[4], "PIEP=");
83 ASSERT_STREQ(r[5], "NANANANA=YES");
43cadb64 84 assert_se(strv_length(r) == 6);
1f28b2de
TA
85}
86
4f7452a8 87TEST(strv_env_replace_strdup) {
73c8cc71
ZJS
88 _cleanup_strv_free_ char **a = NULL;
89
90 assert_se(strv_env_replace_strdup(&a, "a=a") == 1);
91 assert_se(strv_env_replace_strdup(&a, "b=b") == 1);
92 assert_se(strv_env_replace_strdup(&a, "a=A") == 0);
a14af47e 93 assert_se(strv_env_replace_strdup(&a, "c") == -EINVAL);
73c8cc71
ZJS
94
95 assert_se(strv_length(a) == 2);
96 strv_sort(a);
c79e88b3
IK
97 ASSERT_STREQ(a[0], "a=A");
98 ASSERT_STREQ(a[1], "b=b");
73c8cc71
ZJS
99}
100
4f7452a8 101TEST(strv_env_replace_strdup_passthrough) {
a14af47e
ZJS
102 _cleanup_strv_free_ char **a = NULL;
103
104 assert_se(putenv((char*) "a=a") == 0);
105 assert_se(putenv((char*) "b=") == 0);
106 assert_se(unsetenv("c") == 0);
107
108 assert_se(strv_env_replace_strdup_passthrough(&a, "a") == 1);
109 assert_se(strv_env_replace_strdup_passthrough(&a, "b") == 1);
110 assert_se(strv_env_replace_strdup_passthrough(&a, "c") == 1);
111 assert_se(strv_env_replace_strdup_passthrough(&a, "a") == 0);
112 assert_se(strv_env_replace_strdup_passthrough(&a, "$a") == -EINVAL);
113
114 assert_se(strv_length(a) == 3);
c79e88b3
IK
115 ASSERT_STREQ(a[0], "a=a");
116 ASSERT_STREQ(a[1], "b=");
117 ASSERT_STREQ(a[2], "c=");
a14af47e
ZJS
118}
119
4f7452a8 120TEST(strv_env_assign) {
73c8cc71
ZJS
121 _cleanup_strv_free_ char **a = NULL;
122
123 assert_se(strv_env_assign(&a, "a", "a") == 1);
124 assert_se(strv_env_assign(&a, "b", "b") == 1);
125 assert_se(strv_env_assign(&a, "a", "A") == 0);
126 assert_se(strv_env_assign(&a, "b", NULL) == 0);
127
128 assert_se(strv_env_assign(&a, "a=", "B") == -EINVAL);
129
130 assert_se(strv_length(a) == 1);
c79e88b3 131 ASSERT_STREQ(a[0], "a=A");
73c8cc71
ZJS
132}
133
20f8b345
LP
134TEST(strv_env_assignf) {
135 _cleanup_strv_free_ char **a = NULL;
136
137 assert_se(strv_env_assignf(&a, "a", "a") > 0);
138 assert_se(strv_env_assignf(&a, "a", "%c", 'a') == 0);
139
140 assert_se(strv_env_assignf(&a, "c", "xxx%iyyy", 5) > 0);
141 assert_se(strv_length(a) == 2);
142 assert_se(strv_equal(a, STRV_MAKE("a=a", "c=xxx5yyy")));
143 assert_se(strv_env_assignf(&a, "c", NULL) == 0);
144
145 assert_se(strv_env_assignf(&a, "b", "b") > 0);
146 assert_se(strv_env_assignf(&a, "a", "A") == 0);
147 assert_se(strv_env_assignf(&a, "b", NULL) == 0);
148
149 assert_se(strv_env_assignf(&a, "a=", "B") == -EINVAL);
150
151 assert_se(strv_length(a) == 1);
c79e88b3 152 ASSERT_STREQ(a[0], "a=A");
20f8b345
LP
153}
154
40975963
YW
155TEST(strv_env_assign_many) {
156 _cleanup_strv_free_ char **a = NULL;
157
158 assert_se(strv_env_assign_many(&a, "a", "a", "b", "b") >= 0);
159
160 assert_se(strv_length(a) == 2);
161 assert_se(strv_contains(a, "a=a"));
162 assert_se(strv_contains(a, "b=b"));
163
164 assert_se(strv_env_assign_many(&a, "a", "A", "b", "b", "c", "c") >= 0);
165 assert_se(strv_length(a) == 3);
166 assert_se(strv_contains(a, "a=A"));
167 assert_se(strv_contains(a, "b=b"));
168 assert_se(strv_contains(a, "c=c"));
169
170 assert_se(strv_env_assign_many(&a, "b", NULL, "c", "C") >= 0);
171 assert_se(strv_length(a) == 2);
172 assert_se(strv_contains(a, "a=A"));
173 assert_se(strv_contains(a, "c=C"));
174
175 assert_se(strv_env_assign_many(&a, "a=", "B") == -EINVAL);
176 assert_se(strv_length(a) == 2);
177 assert_se(strv_contains(a, "a=A"));
178 assert_se(strv_contains(a, "c=C"));
179}
180
4f7452a8 181TEST(env_strv_get_n) {
37f3ffca
RS
182 const char *_env[] = {
183 "FOO=NO NO NO",
184 "FOO=BAR BAR",
185 "BAR=waldo",
186 "PATH=unset",
187 NULL
188 };
189 char **env = (char**) _env;
190
c79e88b3
IK
191 ASSERT_STREQ(strv_env_get_n(env, "FOO__", 3, 0), "BAR BAR");
192 ASSERT_STREQ(strv_env_get_n(env, "FOO__", 3, REPLACE_ENV_USE_ENVIRONMENT), "BAR BAR");
193 ASSERT_STREQ(strv_env_get_n(env, "FOO", 3, 0), "BAR BAR");
194 ASSERT_STREQ(strv_env_get_n(env, "FOO", 3, REPLACE_ENV_USE_ENVIRONMENT), "BAR BAR");
37f3ffca 195
c79e88b3
IK
196 ASSERT_STREQ(strv_env_get_n(env, "PATH__", 4, 0), "unset");
197 ASSERT_STREQ(strv_env_get_n(env, "PATH", 4, 0), "unset");
198 ASSERT_STREQ(strv_env_get_n(env, "PATH__", 4, REPLACE_ENV_USE_ENVIRONMENT), "unset");
199 ASSERT_STREQ(strv_env_get_n(env, "PATH", 4, REPLACE_ENV_USE_ENVIRONMENT), "unset");
37f3ffca
RS
200
201 env[3] = NULL; /* kill our $PATH */
202
203 assert_se(!strv_env_get_n(env, "PATH__", 4, 0));
204 assert_se(!strv_env_get_n(env, "PATH", 4, 0));
1890c538
ZJS
205 assert_se(streq_ptr(strv_env_get_n(env, "PATH__", 4, REPLACE_ENV_USE_ENVIRONMENT),
206 getenv("PATH")));
207 assert_se(streq_ptr(strv_env_get_n(env, "PATH", 4, REPLACE_ENV_USE_ENVIRONMENT),
208 getenv("PATH")));
37f3ffca
RS
209}
210
4f7452a8 211static void test_replace_env1(bool braceless) {
0b345642
ZJS
212 log_info("/* %s(braceless=%s) */", __func__, yes_no(braceless));
213
ccad1fd0
ZJS
214 const char *env[] = {
215 "FOO=BAR BAR",
216 "BAR=waldo",
217 NULL
218 };
219 _cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL;
220 unsigned flags = REPLACE_ENV_ALLOW_BRACELESS*braceless;
221
f331434d 222 assert_se(replace_env("FOO=$FOO=${FOO}", (char**) env, flags, &t) >= 0);
c79e88b3 223 ASSERT_STREQ(t, braceless ? "FOO=BAR BAR=BAR BAR" : "FOO=$FOO=BAR BAR");
ccad1fd0 224
f331434d 225 assert_se(replace_env("BAR=$BAR=${BAR}", (char**) env, flags, &s) >= 0);
c79e88b3 226 ASSERT_STREQ(s, braceless ? "BAR=waldo=waldo" : "BAR=$BAR=waldo");
ccad1fd0 227
f331434d 228 assert_se(replace_env("BARBAR=$BARBAR=${BARBAR}", (char**) env, flags, &q) >= 0);
c79e88b3 229 ASSERT_STREQ(q, braceless ? "BARBAR==" : "BARBAR=$BARBAR=");
ccad1fd0 230
f331434d 231 assert_se(replace_env("BAR=$BAR$BAR${BAR}${BAR}", (char**) env, flags, &r) >= 0);
c79e88b3 232 ASSERT_STREQ(r, braceless ? "BAR=waldowaldowaldowaldo" : "BAR=$BAR$BARwaldowaldo");
ccad1fd0 233
f331434d 234 assert_se(replace_env("${BAR}$BAR$BAR", (char**) env, flags, &p) >= 0);
c79e88b3 235 ASSERT_STREQ(p, braceless ? "waldowaldowaldo" : "waldo$BAR$BAR");
ccad1fd0
ZJS
236}
237
f50ce8fc 238static void test_replace_env2(bool extended) {
0b345642
ZJS
239 log_info("/* %s(extended=%s) */", __func__, yes_no(extended));
240
f50ce8fc
ZJS
241 const char *env[] = {
242 "FOO=foo",
243 "BAR=bar",
244 NULL
245 };
5ef97a71 246 _cleanup_free_ char *t = NULL, *s = NULL, *q = NULL, *r = NULL, *p = NULL, *x = NULL, *y = NULL;
f50ce8fc
ZJS
247 unsigned flags = REPLACE_ENV_ALLOW_EXTENDED*extended;
248
f331434d 249 assert_se(replace_env("FOO=${FOO:-${BAR}}", (char**) env, flags, &t) >= 0);
c79e88b3 250 ASSERT_STREQ(t, extended ? "FOO=foo" : "FOO=${FOO:-bar}");
f50ce8fc 251
f331434d 252 assert_se(replace_env("BAR=${XXX:-${BAR}}", (char**) env, flags, &s) >= 0);
c79e88b3 253 ASSERT_STREQ(s, extended ? "BAR=bar" : "BAR=${XXX:-bar}");
f50ce8fc 254
f331434d 255 assert_se(replace_env("XXX=${XXX:+${BAR}}", (char**) env, flags, &q) >= 0);
c79e88b3 256 ASSERT_STREQ(q, extended ? "XXX=" : "XXX=${XXX:+bar}");
f50ce8fc 257
f331434d 258 assert_se(replace_env("FOO=${FOO:+${BAR}}", (char**) env, flags, &r) >= 0);
c79e88b3 259 ASSERT_STREQ(r, extended ? "FOO=bar" : "FOO=${FOO:+bar}");
f50ce8fc 260
f331434d 261 assert_se(replace_env("FOO=${FOO:-${BAR}post}", (char**) env, flags, &p) >= 0);
c79e88b3 262 ASSERT_STREQ(p, extended ? "FOO=foo" : "FOO=${FOO:-barpost}");
f50ce8fc 263
f331434d 264 assert_se(replace_env("XXX=${XXX:+${BAR}post}", (char**) env, flags, &x) >= 0);
c79e88b3 265 ASSERT_STREQ(x, extended ? "XXX=" : "XXX=${XXX:+barpost}");
5ef97a71 266
f331434d 267 assert_se(replace_env("FOO=${FOO}between${BAR:-baz}", (char**) env, flags, &y) >= 0);
c79e88b3 268 ASSERT_STREQ(y, extended ? "FOO=foobetweenbar" : "FOO=foobetween${BAR:-baz}");
f50ce8fc
ZJS
269}
270
4f7452a8
JJ
271TEST(replace_env) {
272 test_replace_env1(false);
273 test_replace_env1(true);
274 test_replace_env2(false);
275 test_replace_env2(true);
276}
0b345642 277
4f7452a8 278TEST(replace_env_argv) {
c24eb49e
LP
279 const char *env[] = {
280 "FOO=BAR BAR",
281 "BAR=waldo",
282 NULL
283 };
c24eb49e
LP
284 const char *line[] = {
285 "FOO$FOO",
286 "FOO$FOOFOO",
287 "FOO${FOO}$FOO",
288 "FOO${FOO}",
289 "${FOO}",
290 "$FOO",
291 "$FOO$FOO",
292 "${FOO}${BAR}",
293 "${FOO",
df553b58
MS
294 "FOO$$${FOO}",
295 "$$FOO${FOO}",
b82f58bf
RS
296 "${FOO:-${BAR}}",
297 "${QUUX:-${FOO}}",
298 "${FOO:+${BAR}}",
299 "${QUUX:+${BAR}}",
300 "${FOO:+|${BAR}|}}",
301 "${FOO:+|${BAR}{|}",
c24eb49e
LP
302 NULL
303 };
1f28b2de 304 _cleanup_strv_free_ char **r = NULL;
c24eb49e 305
f331434d 306 assert_se(replace_env_argv((char**) line, (char**) env, &r, NULL, NULL) >= 0);
9b5d6bd9 307 assert_se(r);
c79e88b3
IK
308 ASSERT_STREQ(r[0], "FOO$FOO");
309 ASSERT_STREQ(r[1], "FOO$FOOFOO");
310 ASSERT_STREQ(r[2], "FOOBAR BAR$FOO");
311 ASSERT_STREQ(r[3], "FOOBAR BAR");
312 ASSERT_STREQ(r[4], "BAR BAR");
313 ASSERT_STREQ(r[5], "BAR");
314 ASSERT_STREQ(r[6], "BAR");
315 ASSERT_STREQ(r[7], "BAR BARwaldo");
316 ASSERT_STREQ(r[8], "${FOO");
317 ASSERT_STREQ(r[9], "FOO$BAR BAR");
318 ASSERT_STREQ(r[10], "$FOOBAR BAR");
319 ASSERT_STREQ(r[11], "${FOO:-waldo}");
320 ASSERT_STREQ(r[12], "${QUUX:-BAR BAR}");
321 ASSERT_STREQ(r[13], "${FOO:+waldo}");
322 ASSERT_STREQ(r[14], "${QUUX:+waldo}");
323 ASSERT_STREQ(r[15], "${FOO:+|waldo|}}");
324 ASSERT_STREQ(r[16], "${FOO:+|waldo{|}");
b82f58bf 325 assert_se(strv_length(r) == 17);
1f28b2de 326}
a6ff950e 327
f331434d
LP
328TEST(replace_env_argv_bad) {
329
330 const char *env[] = {
331 "FOO=BAR BAR",
332 "BAR=waldo",
333 NULL
334 };
335
336 const char *line[] = {
337 "$FOO",
338 "A${FOO}B",
339 "a${~}${%}b",
340 "x${}y",
341 "$UNSET2",
342 "z${UNSET3}z${UNSET1}z",
343 "piff${UNSET2}piff",
344 NULL
345 };
346
347 _cleanup_strv_free_ char **bad = NULL, **unset = NULL, **replaced = NULL;
348
349 assert_se(replace_env_argv((char**) line, (char**) env, &replaced, &unset, &bad) >= 0);
350
351 assert_se(strv_equal(replaced, STRV_MAKE(
352 "BAR",
353 "BAR",
354 "ABAR BARB",
355 "ab",
356 "xy",
357 "zzz",
358 "piffpiff")));
359
360 assert_se(strv_equal(unset, STRV_MAKE(
361 "UNSET1",
362 "UNSET2",
363 "UNSET3")));
364 assert_se(strv_equal(bad, STRV_MAKE("",
365 "%",
366 "~")));
367}
368
4f7452a8 369TEST(env_clean) {
0b345642
ZJS
370 _cleanup_strv_free_ char **e = strv_new("FOOBAR=WALDO",
371 "FOOBAR=WALDO",
372 "FOOBAR",
373 "F",
374 "X=",
375 "F=F",
376 "=",
377 "=F",
378 "",
379 "0000=000",
380 "äöüß=abcd",
381 "abcd=äöüß",
382 "xyz\n=xyz",
383 "xyz=xyz\n",
384 "another=one",
b45c068d 385 "another=final one",
e1e8c60a 386 "CRLF=\r\n",
30927a24 387 "LESS_TERMCAP_mb=\x1b[01;31m",
b45c068d 388 "BASH_FUNC_foo%%=() { echo foo\n}");
9b5d6bd9
LP
389 assert_se(e);
390 assert_se(!strv_env_is_valid(e));
391 assert_se(strv_env_clean(e) == e);
392 assert_se(strv_env_is_valid(e));
4d1a6904 393
c79e88b3
IK
394 ASSERT_STREQ(e[0], "FOOBAR=WALDO");
395 ASSERT_STREQ(e[1], "X=");
396 ASSERT_STREQ(e[2], "F=F");
397 ASSERT_STREQ(e[3], "abcd=äöüß");
398 ASSERT_STREQ(e[4], "xyz=xyz\n");
399 ASSERT_STREQ(e[5], "another=final one");
400 ASSERT_STREQ(e[6], "CRLF=\r\n");
401 ASSERT_STREQ(e[7], "LESS_TERMCAP_mb=\x1b[01;31m");
5152b845 402 ASSERT_NULL(e[8]);
4d1a6904
LP
403}
404
4f7452a8 405TEST(env_name_is_valid) {
8354c34e
TA
406 assert_se(env_name_is_valid("test"));
407
408 assert_se(!env_name_is_valid(NULL));
409 assert_se(!env_name_is_valid(""));
b8c83cfc
ZJS
410 assert_se(!env_name_is_valid("xxx\a"));
411 assert_se(!env_name_is_valid("xxx\007b"));
412 assert_se(!env_name_is_valid("\007\009"));
ff461576 413 assert_se(!env_name_is_valid("5_starting_with_a_number_is_wrong"));
8354c34e
TA
414 assert_se(!env_name_is_valid("#¤%&?_only_numbers_letters_and_underscore_allowed"));
415}
416
4f7452a8 417TEST(env_value_is_valid) {
b8c83cfc
ZJS
418 assert_se(env_value_is_valid(""));
419 assert_se(env_value_is_valid("głąb kapuściany"));
420 assert_se(env_value_is_valid("printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
b4346b9a
FB
421 assert_se(env_value_is_valid("tab\tcharacter"));
422 assert_se(env_value_is_valid("new\nline"));
30927a24
ZJS
423 assert_se(env_value_is_valid("Show this?\rNope. Show that!"));
424 assert_se(env_value_is_valid("new DOS\r\nline"));
425
426 assert_se(!env_value_is_valid("\xc5")); /* A truncated utf-8-encoded "ł".
427 * We currently disallow that. */
b8c83cfc
ZJS
428}
429
4f7452a8 430TEST(env_assignment_is_valid) {
b8c83cfc
ZJS
431 assert_se(env_assignment_is_valid("a="));
432 assert_se(env_assignment_is_valid("b=głąb kapuściany"));
433 assert_se(env_assignment_is_valid("c=\\007\\009\\011"));
434 assert_se(env_assignment_is_valid("e=printf \"\\x1b]0;<mock-chroot>\\x07<mock-chroot>\""));
b4346b9a
FB
435 assert_se(env_assignment_is_valid("f=tab\tcharacter"));
436 assert_se(env_assignment_is_valid("g=new\nline"));
b8c83cfc
ZJS
437
438 assert_se(!env_assignment_is_valid("="));
439 assert_se(!env_assignment_is_valid("a b="));
440 assert_se(!env_assignment_is_valid("a ="));
441 assert_se(!env_assignment_is_valid(" b="));
ff461576
ZJS
442 /* no dots or dashes: http://tldp.org/LDP/abs/html/gotchas.html */
443 assert_se(!env_assignment_is_valid("a.b="));
444 assert_se(!env_assignment_is_valid("a-b="));
b8c83cfc
ZJS
445 assert_se(!env_assignment_is_valid("\007=głąb kapuściany"));
446 assert_se(!env_assignment_is_valid("c\009=\007\009\011"));
447 assert_se(!env_assignment_is_valid("głąb=printf \"\x1b]0;<mock-chroot>\x07<mock-chroot>\""));
448}
449
4f7452a8 450TEST(putenv_dup) {
fa256f43 451 assert_se(putenv_dup("A=a1", true) == 0);
c79e88b3 452 ASSERT_STREQ(getenv("A"), "a1");
fa256f43 453 assert_se(putenv_dup("A=a1", true) == 0);
c79e88b3 454 ASSERT_STREQ(getenv("A"), "a1");
fa256f43 455 assert_se(putenv_dup("A=a2", false) == 0);
c79e88b3 456 ASSERT_STREQ(getenv("A"), "a1");
fa256f43 457 assert_se(putenv_dup("A=a2", true) == 0);
c79e88b3 458 ASSERT_STREQ(getenv("A"), "a2");
fa256f43
ZJS
459}
460
4f7452a8 461TEST(setenv_systemd_exec_pid) {
cfd1c6e2
YW
462 _cleanup_free_ char *saved = NULL;
463 const char *e;
464 pid_t p;
465
cfd1c6e2
YW
466 e = getenv("SYSTEMD_EXEC_PID");
467 if (e)
468 assert_se(saved = strdup(e));
469
470 assert_se(unsetenv("SYSTEMD_EXEC_PID") >= 0);
471 assert_se(setenv_systemd_exec_pid(true) == 0);
472 assert_se(!getenv("SYSTEMD_EXEC_PID"));
473
474 assert_se(setenv("SYSTEMD_EXEC_PID", "*", 1) >= 0);
475 assert_se(setenv_systemd_exec_pid(true) == 0);
476 assert_se(e = getenv("SYSTEMD_EXEC_PID"));
c79e88b3 477 ASSERT_STREQ(e, "*");
cfd1c6e2
YW
478
479 assert_se(setenv("SYSTEMD_EXEC_PID", "123abc", 1) >= 0);
480 assert_se(setenv_systemd_exec_pid(true) == 1);
481 assert_se(e = getenv("SYSTEMD_EXEC_PID"));
482 assert_se(parse_pid(e, &p) >= 0);
483 assert_se(p == getpid_cached());
484
485 assert_se(unsetenv("SYSTEMD_EXEC_PID") >= 0);
486 assert_se(setenv_systemd_exec_pid(false) == 1);
487 assert_se(e = getenv("SYSTEMD_EXEC_PID"));
488 assert_se(parse_pid(e, &p) >= 0);
489 assert_se(p == getpid_cached());
490
491 assert_se(set_unset_env("SYSTEMD_EXEC_PID", saved, 1) >= 0);
492}
493
e99ca147 494TEST(getenv_steal_erase) {
7a6abbe9
LP
495 int r;
496
e9ccae31 497 r = safe_fork("(sd-getenvstealerase)", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT, NULL);
7a6abbe9
LP
498 if (r == 0) {
499 _cleanup_strv_free_ char **l = NULL;
7a6abbe9
LP
500
501 /* child */
502
e99ca147 503 assert_se(getenv_steal_erase("thisenvvardefinitelywontexist", NULL) == 0);
7a6abbe9
LP
504
505 l = strv_new("FOO=BAR", "QUUX=PIFF", "ONE=TWO", "A=B");
506 assert_se(strv_length(l) == 4);
507
508 environ = l;
509
510 STRV_FOREACH(e, environ) {
e99ca147 511 _cleanup_free_ char *n = NULL, *copy1 = NULL, *copy2 = NULL;
7a6abbe9
LP
512 char *eq;
513
514 eq = strchr(*e, '=');
515 if (!eq)
516 continue;
517
518 n = strndup(*e, eq - *e);
519 assert_se(n);
520
e99ca147
LP
521 copy1 = strdup(eq + 1);
522 assert_se(copy1);
523
c79e88b3 524 ASSERT_STREQ(getenv(n), copy1);
7a6abbe9 525 assert_se(getenv(n) == eq + 1);
e99ca147 526 assert_se(getenv_steal_erase(n, &copy2) > 0);
c79e88b3 527 ASSERT_STREQ(copy1, copy2);
7a6abbe9
LP
528 assert_se(isempty(eq + 1));
529 assert_se(!getenv(n));
530 }
531
532 environ = NULL;
533 l = strv_free(l);
534
535 _exit(EXIT_SUCCESS);
536 }
537
538 assert_se(r > 0);
539}
540
6cc19afa 541TEST(strv_env_name_is_valid) {
fd762319
T
542 assert_se(strv_env_name_is_valid(STRV_MAKE("HOME", "USER", "SHELL", "PATH")));
543 assert_se(!strv_env_name_is_valid(STRV_MAKE("", "PATH", "home", "user", "SHELL")));
544 assert_se(!strv_env_name_is_valid(STRV_MAKE("HOME", "USER", "SHELL", "USER")));
6cc19afa 545}
546
192242c9
FS
547TEST(getenv_path_list) {
548 _cleanup_strv_free_ char **path_list = NULL;
549
550 /* Empty paths */
551 FOREACH_STRING(s, "", ":", ":::::", " : ::: :: :") {
552 assert_se(setenv("TEST_GETENV_PATH_LIST", s, 1) >= 0);
553 assert_se(getenv_path_list("TEST_GETENV_PATH_LIST", &path_list) == -EINVAL);
554 assert_se(!path_list);
555 }
556
557 /* Invalid paths */
558 FOREACH_STRING(s, ".", "..", "/../", "/", "/foo/bar/baz/../foo", "foo/bar/baz") {
559 assert_se(setenv("TEST_GETENV_PATH_LIST", s, 1) >= 0);
560 assert_se(getenv_path_list("TEST_GETENV_PATH_LIST", &path_list) == -EINVAL);
561 assert_se(!path_list);
562 }
563
564 /* Valid paths mixed with invalid ones */
565 assert_se(setenv("TEST_GETENV_PATH_LIST", "/foo:/bar/baz:/../:/hello", 1) >= 0);
566 assert_se(getenv_path_list("TEST_GETENV_PATH_LIST", &path_list) == -EINVAL);
567 assert_se(!path_list);
568
569 /* Finally some valid paths */
570 assert_se(setenv("TEST_GETENV_PATH_LIST", "/foo:/bar/baz:/hello/world:/path with spaces:/final", 1) >= 0);
571 assert_se(getenv_path_list("TEST_GETENV_PATH_LIST", &path_list) >= 0);
c79e88b3
IK
572 ASSERT_STREQ(path_list[0], "/foo");
573 ASSERT_STREQ(path_list[1], "/bar/baz");
574 ASSERT_STREQ(path_list[2], "/hello/world");
575 ASSERT_STREQ(path_list[3], "/path with spaces");
576 ASSERT_STREQ(path_list[4], "/final");
5152b845 577 ASSERT_NULL(path_list[5]);
192242c9
FS
578
579 assert_se(unsetenv("TEST_GETENV_PATH_LIST") >= 0);
580}
581
7633001c
YW
582TEST(strv_env_get_merged) {
583 char **l = STRV_MAKE("ONE", "1", "TWO", "2", "THREE", "3", "FOUR", "4", "FIVE", "5"),
584 **expected = STRV_MAKE("ONE=1", "TWO=2", "THREE=3", "FOUR=4", "FIVE=5");
585 _cleanup_strv_free_ char **m = NULL;
586
587 ASSERT_OK(strv_env_get_merged(NULL, &m));
588 ASSERT_NULL(m);
589 ASSERT_OK(strv_env_get_merged(l, &m));
590 ASSERT_TRUE(strv_equal(m, expected));
591}
592
4f7452a8 593DEFINE_TEST_MAIN(LOG_DEBUG);