1*bf6873c5SCy Schubert /*
2*bf6873c5SCy Schubert * PAM utility vector library test suite.
3*bf6873c5SCy Schubert *
4*bf6873c5SCy Schubert * The canonical version of this file is maintained in the rra-c-util package,
5*bf6873c5SCy Schubert * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
6*bf6873c5SCy Schubert *
7*bf6873c5SCy Schubert * Written by Russ Allbery <eagle@eyrie.org>
8*bf6873c5SCy Schubert * Copyright 2014, 2016, 2018-2019 Russ Allbery <eagle@eyrie.org>
9*bf6873c5SCy Schubert * Copyright 2010-2011, 2013
10*bf6873c5SCy Schubert * The Board of Trustees of the Leland Stanford Junior University
11*bf6873c5SCy Schubert *
12*bf6873c5SCy Schubert * Copying and distribution of this file, with or without modification, are
13*bf6873c5SCy Schubert * permitted in any medium without royalty provided the copyright notice and
14*bf6873c5SCy Schubert * this notice are preserved. This file is offered as-is, without any
15*bf6873c5SCy Schubert * warranty.
16*bf6873c5SCy Schubert *
17*bf6873c5SCy Schubert * SPDX-License-Identifier: FSFAP
18*bf6873c5SCy Schubert */
19*bf6873c5SCy Schubert
20*bf6873c5SCy Schubert #include <config.h>
21*bf6873c5SCy Schubert #include <portable/system.h>
22*bf6873c5SCy Schubert
23*bf6873c5SCy Schubert #include <sys/wait.h>
24*bf6873c5SCy Schubert
25*bf6873c5SCy Schubert #include <pam-util/vector.h>
26*bf6873c5SCy Schubert #include <tests/tap/basic.h>
27*bf6873c5SCy Schubert #include <tests/tap/string.h>
28*bf6873c5SCy Schubert
29*bf6873c5SCy Schubert
30*bf6873c5SCy Schubert int
main(void)31*bf6873c5SCy Schubert main(void)
32*bf6873c5SCy Schubert {
33*bf6873c5SCy Schubert struct vector *vector, *ovector, *copy;
34*bf6873c5SCy Schubert char *command, *string;
35*bf6873c5SCy Schubert const char *env[2];
36*bf6873c5SCy Schubert pid_t child;
37*bf6873c5SCy Schubert size_t i;
38*bf6873c5SCy Schubert const char cstring[] = "This is a\ttest. ";
39*bf6873c5SCy Schubert
40*bf6873c5SCy Schubert plan(60);
41*bf6873c5SCy Schubert
42*bf6873c5SCy Schubert vector = vector_new();
43*bf6873c5SCy Schubert ok(vector != NULL, "vector_new returns non-NULL");
44*bf6873c5SCy Schubert if (vector == NULL)
45*bf6873c5SCy Schubert bail("vector_new returned NULL");
46*bf6873c5SCy Schubert ok(vector_add(vector, cstring), "vector_add succeeds");
47*bf6873c5SCy Schubert is_int(1, vector->count, "vector_add increases count");
48*bf6873c5SCy Schubert ok(vector->strings[0] != cstring, "...and allocated new memory");
49*bf6873c5SCy Schubert ok(vector_resize(vector, 4), "vector_resize succeeds");
50*bf6873c5SCy Schubert is_int(4, vector->allocated, "vector_resize works");
51*bf6873c5SCy Schubert ok(vector_add(vector, cstring), "vector_add #2");
52*bf6873c5SCy Schubert ok(vector_add(vector, cstring), "vector_add #3");
53*bf6873c5SCy Schubert ok(vector_add(vector, cstring), "vector_add #4");
54*bf6873c5SCy Schubert is_int(4, vector->allocated, "...and no reallocation when adding strings");
55*bf6873c5SCy Schubert is_int(4, vector->count, "...and the count matches");
56*bf6873c5SCy Schubert is_string(cstring, vector->strings[0], "added the right string");
57*bf6873c5SCy Schubert is_string(cstring, vector->strings[1], "added the right string");
58*bf6873c5SCy Schubert is_string(cstring, vector->strings[2], "added the right string");
59*bf6873c5SCy Schubert is_string(cstring, vector->strings[3], "added the right string");
60*bf6873c5SCy Schubert ok(vector->strings[1] != vector->strings[2], "each pointer is different");
61*bf6873c5SCy Schubert ok(vector->strings[2] != vector->strings[3], "each pointer is different");
62*bf6873c5SCy Schubert ok(vector->strings[3] != vector->strings[0], "each pointer is different");
63*bf6873c5SCy Schubert ok(vector->strings[0] != cstring, "each pointer is different");
64*bf6873c5SCy Schubert copy = vector_copy(vector);
65*bf6873c5SCy Schubert ok(copy != NULL, "vector_copy returns non-NULL");
66*bf6873c5SCy Schubert if (copy == NULL)
67*bf6873c5SCy Schubert bail("vector_copy returned NULL");
68*bf6873c5SCy Schubert is_int(4, copy->count, "...and has right count");
69*bf6873c5SCy Schubert is_int(4, copy->allocated, "...and has right allocated count");
70*bf6873c5SCy Schubert for (i = 0; i < 4; i++) {
71*bf6873c5SCy Schubert is_string(cstring, copy->strings[i], "...and string %lu is right",
72*bf6873c5SCy Schubert (unsigned long) i);
73*bf6873c5SCy Schubert ok(copy->strings[i] != vector->strings[i],
74*bf6873c5SCy Schubert "...and pointer %lu is different", (unsigned long) i);
75*bf6873c5SCy Schubert }
76*bf6873c5SCy Schubert vector_free(copy);
77*bf6873c5SCy Schubert vector_clear(vector);
78*bf6873c5SCy Schubert is_int(0, vector->count, "vector_clear works");
79*bf6873c5SCy Schubert is_int(4, vector->allocated, "...but doesn't free the allocation");
80*bf6873c5SCy Schubert string = strdup(cstring);
81*bf6873c5SCy Schubert if (string == NULL)
82*bf6873c5SCy Schubert sysbail("cannot allocate memory");
83*bf6873c5SCy Schubert ok(vector_add(vector, cstring), "vector_add succeeds");
84*bf6873c5SCy Schubert ok(vector_add(vector, string), "vector_add succeeds");
85*bf6873c5SCy Schubert is_int(2, vector->count, "added two strings to the vector");
86*bf6873c5SCy Schubert ok(vector->strings[1] != string, "...and the pointers are different");
87*bf6873c5SCy Schubert ok(vector_resize(vector, 1), "vector_resize succeeds");
88*bf6873c5SCy Schubert is_int(1, vector->count, "vector_resize shrinks the vector");
89*bf6873c5SCy Schubert ok(vector->strings[0] != cstring, "...and the pointer is different");
90*bf6873c5SCy Schubert vector_free(vector);
91*bf6873c5SCy Schubert free(string);
92*bf6873c5SCy Schubert
93*bf6873c5SCy Schubert vector = vector_split_multi("foo, bar, baz", ", ", NULL);
94*bf6873c5SCy Schubert ok(vector != NULL, "vector_split_multi returns non-NULL");
95*bf6873c5SCy Schubert if (vector == NULL)
96*bf6873c5SCy Schubert bail("vector_split_multi returned NULL");
97*bf6873c5SCy Schubert is_int(3, vector->count, "vector_split_multi returns right count");
98*bf6873c5SCy Schubert is_string("foo", vector->strings[0], "...first string");
99*bf6873c5SCy Schubert is_string("bar", vector->strings[1], "...second string");
100*bf6873c5SCy Schubert is_string("baz", vector->strings[2], "...third string");
101*bf6873c5SCy Schubert ovector = vector;
102*bf6873c5SCy Schubert vector = vector_split_multi("", ", ", vector);
103*bf6873c5SCy Schubert ok(vector != NULL, "reuse of vector doesn't return NULL");
104*bf6873c5SCy Schubert ok(vector == ovector, "...and reuses the same vector pointer");
105*bf6873c5SCy Schubert is_int(0, vector->count, "vector_split_multi reuse with empty string");
106*bf6873c5SCy Schubert is_int(3, vector->allocated, "...and doesn't free allocation");
107*bf6873c5SCy Schubert vector = vector_split_multi(",,, foo, ", ", ", vector);
108*bf6873c5SCy Schubert ok(vector != NULL, "reuse of vector doesn't return NULL");
109*bf6873c5SCy Schubert is_int(1, vector->count, "vector_split_multi with extra separators");
110*bf6873c5SCy Schubert is_string("foo", vector->strings[0], "...first string");
111*bf6873c5SCy Schubert vector = vector_split_multi(", , ", ", ", vector);
112*bf6873c5SCy Schubert is_int(0, vector->count, "vector_split_multi with only separators");
113*bf6873c5SCy Schubert vector_free(vector);
114*bf6873c5SCy Schubert
115*bf6873c5SCy Schubert vector = vector_new();
116*bf6873c5SCy Schubert ok(vector_add(vector, "/bin/sh"), "vector_add succeeds");
117*bf6873c5SCy Schubert ok(vector_add(vector, "-c"), "vector_add succeeds");
118*bf6873c5SCy Schubert basprintf(&command, "echo ok %lu - vector_exec", testnum++);
119*bf6873c5SCy Schubert ok(vector_add(vector, command), "vector_add succeeds");
120*bf6873c5SCy Schubert child = fork();
121*bf6873c5SCy Schubert if (child < 0)
122*bf6873c5SCy Schubert sysbail("unable to fork");
123*bf6873c5SCy Schubert else if (child == 0)
124*bf6873c5SCy Schubert if (vector_exec("/bin/sh", vector) < 0)
125*bf6873c5SCy Schubert sysdiag("unable to exec /bin/sh");
126*bf6873c5SCy Schubert waitpid(child, NULL, 0);
127*bf6873c5SCy Schubert vector_free(vector);
128*bf6873c5SCy Schubert free(command);
129*bf6873c5SCy Schubert
130*bf6873c5SCy Schubert vector = vector_new();
131*bf6873c5SCy Schubert ok(vector_add(vector, "/bin/sh"), "vector_add succeeds");
132*bf6873c5SCy Schubert ok(vector_add(vector, "-c"), "vector_add succeeds");
133*bf6873c5SCy Schubert ok(vector_add(vector, "echo ok $NUMBER - vector_exec_env"),
134*bf6873c5SCy Schubert "vector_add succeeds");
135*bf6873c5SCy Schubert basprintf(&string, "NUMBER=%lu", testnum++);
136*bf6873c5SCy Schubert env[0] = string;
137*bf6873c5SCy Schubert env[1] = NULL;
138*bf6873c5SCy Schubert child = fork();
139*bf6873c5SCy Schubert if (child < 0)
140*bf6873c5SCy Schubert sysbail("unable to fork");
141*bf6873c5SCy Schubert else if (child == 0)
142*bf6873c5SCy Schubert if (vector_exec_env("/bin/sh", vector, env) < 0)
143*bf6873c5SCy Schubert sysdiag("unable to exec /bin/sh");
144*bf6873c5SCy Schubert waitpid(child, NULL, 0);
145*bf6873c5SCy Schubert vector_free(vector);
146*bf6873c5SCy Schubert free(string);
147*bf6873c5SCy Schubert
148*bf6873c5SCy Schubert return 0;
149*bf6873c5SCy Schubert }
150