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 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