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