1 /*
2  * ProFTPD - FTP server testsuite
3  * Copyright (c) 2008-2015 The ProFTPD Project team
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  *
19  * As a special exemption, The ProFTPD Project team and other respective
20  * copyright holders give permission to link this program with OpenSSL, and
21  * distribute the resulting executable, without including the source code for
22  * OpenSSL in the source distribution.
23  */
24 
25 /* Array API tests */
26 
27 #include "tests.h"
28 
29 static pool *p = NULL;
30 
set_up(void)31 static void set_up(void) {
32   if (p == NULL) {
33     p = make_sub_pool(NULL);
34   }
35 }
36 
tear_down(void)37 static void tear_down(void) {
38   if (p) {
39     destroy_pool(p);
40     p = NULL;
41   }
42 }
43 
START_TEST(make_array_test)44 START_TEST (make_array_test) {
45   array_header *list;
46 
47   list = make_array(NULL, 0, 0);
48   fail_unless(list == NULL, "Failed to handle null arguments");
49   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
50 
51   list = make_array(p, 0, 0);
52   fail_unless(list == NULL, "Failed to handle null arguments");
53   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
54 
55   list = make_array(p, 1, 0);
56   fail_unless(list == NULL, "Failed to handle null arguments");
57   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
58 
59   list = make_array(p, 0, 1);
60   fail_unless(list != NULL, "Failed to create an array_header: %s",
61     strerror(errno));
62   fail_unless(list->nalloc == 1, "Expected list->nalloc of %u, got %d",
63     1, list->nalloc);
64 
65   list = make_array(p, 3, 1);
66   fail_unless(list != NULL, "Failed to create an array_header: %s",
67     strerror(errno));
68 
69   fail_unless(list->pool == p, "List pool doesn't given pool; "
70     "expected %p, got %p", p, list->pool);
71   fail_unless(list->elts != NULL, "Expected non-null elements pointer");
72   fail_unless(list->nalloc == 3, "Expected list->nalloc of %u, got %d",
73     3, list->nalloc);
74   fail_unless(list->nelts == 0, "Expected list->nelts of %u, got %d",
75     0, list->nelts);
76   fail_unless(list->elt_size == 1, "Expect list element size of %u, got %d",
77     1, list->elt_size);
78 }
79 END_TEST
80 
START_TEST(push_array_test)81 START_TEST (push_array_test) {
82   array_header *list;
83   void *res;
84 
85   res = push_array(NULL);
86   fail_unless(res == NULL, "Failed to handle null arguments");
87   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL for null args");
88 
89   list = make_array(p, 0, 1);
90 
91   res = push_array(list);
92   fail_unless(res != NULL, "Failed to allocate new list element");
93   fail_unless(list->nalloc == 1, "Incremented alloc elements needlessly ("
94     "expected %u, got %d)", 1, list->nalloc);
95   fail_unless(list->nelts == 1, "Failed to increment element count "
96     "(expected %u, got %d)", 1, list->nelts);
97 
98   res = push_array(list);
99   fail_unless(res != NULL, "Failed to allocate new list element");
100   fail_unless(list->nalloc == 2, "Incremented alloc elements needlessly "
101     "(expected %u, got %d)", 2, list->nalloc);
102   fail_unless(list->nelts == 2, "Failed to increment element count "
103     "(expected %u, got %d)", 2, list->nelts);
104 
105   res = push_array(list);
106   fail_unless(res != NULL, "Failed to allocate new list element");
107   fail_unless(list->nalloc == 4, "Incremented alloc elements needlessly "
108     "(expected %u, got %d)", 4, list->nalloc);
109   fail_unless(list->nelts == 3, "Failed to increment element count "
110     "(expected %u, got %d)", 3, list->nelts);
111 
112   res = push_array(list);
113   fail_unless(res != NULL, "Failed to allocate new list element");
114   fail_unless(list->nalloc == 4, "Incremented alloc elements needlessly "
115     "(expected %u, got %d)", 4, list->nalloc);
116   fail_unless(list->nelts == 4, "Failed to increment element count "
117     "(expected %u, got %d)", 4, list->nelts);
118 }
119 END_TEST
120 
START_TEST(array_cat_test)121 START_TEST (array_cat_test) {
122   array_header *src, *dst;
123 
124   mark_point();
125 
126   /* This should not segfault. */
127   array_cat(NULL, NULL);
128 
129   dst = make_array(p, 0, 1);
130   mark_point();
131   array_cat(dst, NULL);
132 
133   src = make_array(p, 0, 1);
134   mark_point();
135   array_cat(NULL, src);
136 
137   mark_point();
138   array_cat(dst, src);
139 
140   fail_unless(dst->nalloc == 1, "Wrong dst alloc count (expected %u, got %d)",
141     1, dst->nalloc);
142   fail_unless(dst->nelts == 0, "Wrong dst item count (expected %u, got %d)",
143     0, dst->nelts);
144 
145   push_array(src);
146   array_cat(dst, src);
147 
148   fail_unless(dst->nalloc == 1, "Wrong dst alloc count (expected %u, got %d)",
149     1, dst->nalloc);
150   fail_unless(dst->nelts == 1, "Wrong dst item count (expected %u, got %d)",
151     1, dst->nelts);
152 
153   push_array(src);
154   push_array(src);
155   push_array(src);
156   array_cat(dst, src);
157 
158   fail_unless(dst->nalloc == 8, "Wrong dst alloc count (expected %u, got %d)",
159     8, dst->nalloc);
160   fail_unless(dst->nelts == 5, "Wrong dst item count (expected %u, got %d)",
161     5, dst->nelts);
162 }
163 END_TEST
164 
START_TEST(array_cat2_test)165 START_TEST (array_cat2_test) {
166   array_header *src, *dst;
167   int res;
168 
169   mark_point();
170 
171   res = array_cat2(NULL, NULL);
172   fail_unless(res < 0, "Failed to handle null arguments");
173   fail_unless(errno == EINVAL, "Expected errno EINVAL, got '%s' (%d)",
174     strerror(errno), errno);
175 
176   dst = make_array(p, 0, 1);
177   mark_point();
178   res = array_cat2(dst, NULL);
179   fail_unless(res < 0, "Failed to handle null arguments");
180   fail_unless(errno == EINVAL, "Expected errno EINVAL, got '%s' (%d)",
181     strerror(errno), errno);
182 
183   src = make_array(p, 0, 1);
184   mark_point();
185   res = array_cat2(NULL, src);
186   fail_unless(res < 0, "Failed to handle null arguments");
187   fail_unless(errno == EINVAL, "Expected errno EINVAL, got '%s' (%d)",
188     strerror(errno), errno);
189 
190   mark_point();
191   res = array_cat2(dst, src);
192   fail_unless(res == 0, "Failed to concatenate arrays: %s", strerror(errno));
193 
194   fail_unless(dst->nalloc == 1, "Wrong dst alloc count (expected %u, got %d)",
195     1, dst->nalloc);
196   fail_unless(dst->nelts == 0, "Wrong dst item count (expected %u, got %d)",
197     0, dst->nelts);
198 
199   push_array(src);
200   res = array_cat2(dst, src);
201   fail_unless(res == 0, "Failed to concatenate arrays: %s", strerror(errno));
202 
203   fail_unless(dst->nalloc == 1, "Wrong dst alloc count (expected %u, got %d)",
204     1, dst->nalloc);
205   fail_unless(dst->nelts == 1, "Wrong dst item count (expected %u, got %d)",
206     1, dst->nelts);
207 
208   push_array(src);
209   push_array(src);
210   push_array(src);
211   res = array_cat2(dst, src);
212   fail_unless(res == 0, "Failed to concatenate arrays: %s", strerror(errno));
213 
214   fail_unless(dst->nalloc == 8, "Wrong dst alloc count (expected %u, got %d)",
215     8, dst->nalloc);
216   fail_unless(dst->nelts == 5, "Wrong dst item count (expected %u, got %d)",
217     5, dst->nelts);
218 }
219 END_TEST
220 
START_TEST(clear_array_test)221 START_TEST (clear_array_test) {
222   array_header *list;
223 
224   mark_point();
225 
226   /* This should not segfault. */
227   clear_array(NULL);
228 
229   list = make_array(p, 0, 1);
230   push_array(list);
231   push_array(list);
232 
233   fail_unless(list->nalloc == 2, "Wrong list alloc count (expected %u, got %d)",
234     2, list->nalloc);
235   fail_unless(list->nelts == 2, "Wrong list item count (expected %u, got %d)",
236     2, list->nelts);
237 
238   clear_array(list);
239 
240   fail_unless(list->nalloc == 2, "Wrong list alloc count (expected %u, got %d)",
241     2, list->nalloc);
242   fail_unless(list->nelts == 0, "Wrong list item count (expected %u, got %d)",
243     0, list->nelts);
244 }
245 END_TEST
246 
START_TEST(copy_array_test)247 START_TEST (copy_array_test) {
248   array_header *list, *src;
249 
250   list = copy_array(NULL, NULL);
251   fail_unless(list == NULL, "Failed to handle null arguments");
252   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
253 
254   src = make_array(p, 0, 1);
255 
256   list = copy_array(NULL, src);
257   fail_unless(list == NULL, "Failed to handle null arguments");
258   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
259 
260   list = copy_array(p, NULL);
261   fail_unless(list == NULL, "Failed to handle null arguments");
262   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
263 
264   push_array(src);
265 
266   list = copy_array(p, src);
267   fail_unless(list != NULL, "Failed to copy list");
268   fail_unless(list->elt_size == src->elt_size,
269     "Copy item size wrong (expected %d, got %d)", src->elt_size,
270     list->elt_size);
271   fail_unless(list->nalloc == src->nalloc,
272     "Copy nalloc wrong (expected %d, got %d)", src->nalloc, list->nalloc);
273   fail_unless(list->nelts == src->nelts,
274     "Copy nelts wrong (expected %d, got %d)", src->nelts, list->nelts);
275 }
276 END_TEST
277 
START_TEST(copy_array_str_test)278 START_TEST (copy_array_str_test) {
279   array_header *list, *src;
280   char *elt, **elts;
281 
282   src = make_array(p, 0, sizeof(char *));
283 
284   list = copy_array_str(NULL, NULL);
285   fail_unless(list == NULL, "Failed to handle null arguments");
286   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
287 
288   list = copy_array_str(NULL, src);
289   fail_unless(list == NULL, "Failed to handle null arguments");
290   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
291 
292   list = copy_array_str(p, NULL);
293   fail_unless(list == NULL, "Failed to handle null arguments");
294   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
295 
296   *((char **) push_array(src)) = pstrdup(p, "foo");
297   *((char **) push_array(src)) = pstrdup(p, "bar");
298 
299   list = copy_array_str(p, src);
300 
301   fail_unless(list->elt_size == src->elt_size,
302     "Copy item size wrong (expected %d, got %d)", src->elt_size,
303     list->elt_size);
304   fail_unless(list->nalloc == src->nalloc,
305     "Copy nalloc wrong (expected %d, got %d)", src->nalloc, list->nalloc);
306   fail_unless(list->nelts == src->nelts,
307     "Copy nelts wrong (expected %d, got %d)", src->nelts, list->nelts);
308 
309   elts = list->elts;
310 
311   elt = elts[0];
312   fail_unless(strcmp(elt, "foo") == 0,
313     "Improper copy (expected '%s', got '%s')", "foo", elt);
314 
315   elt = elts[1];
316   fail_unless(strcmp(elt, "bar") == 0,
317     "Improper copy (expected '%s', got '%s')", "bar", elt);
318 }
319 END_TEST
320 
START_TEST(copy_array_hdr_test)321 START_TEST (copy_array_hdr_test) {
322   array_header *list, *src;
323   int elt, *elts;
324 
325   src = make_array(p, 0, sizeof(int));
326 
327   list = copy_array_hdr(NULL, NULL);
328   fail_unless(list == NULL, "Failed to handle null arguments");
329   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
330 
331   list = copy_array_hdr(NULL, src);
332   fail_unless(list == NULL, "Failed to handle null arguments");
333   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
334 
335   list = copy_array_hdr(p, NULL);
336   fail_unless(list == NULL, "Failed to handle null arguments");
337   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
338 
339   *((int *) push_array(src)) = -1;
340   *((int *) push_array(src)) = 2;
341   *((int *) push_array(src)) = 2476;
342 
343   list = copy_array_hdr(p, src);
344 
345   fail_unless(list->elt_size == src->elt_size,
346     "Copy item size wrong (expected %d, got %d)", src->elt_size,
347     list->elt_size);
348   fail_unless(list->elts == src->elts,
349     "Copy elts wrong (expected %p, got %p)", src->elts, list->elts);
350   fail_unless(list->nelts == src->nelts,
351     "Copy nelts wrong (expected %d, got %d)", src->nelts, list->nelts);
352 
353   fail_unless(list->nalloc != src->nalloc,
354     "Copy nalloc wrong (expected %d, got %d)", src->nalloc, list->nalloc);
355   fail_unless(list->nalloc == 3,
356     "Copy nalloc wrong (expected %d, got %d)", 3, list->nalloc);
357 
358   elts = list->elts;
359 
360   elt = elts[0];
361   fail_unless(elt == -1, "Improper copy (expected %d, got %d)", -1, elt);
362 
363   elt = elts[1];
364   fail_unless(elt == 2, "Improper copy (expected %d, got %d)", 2, elt);
365 
366   elt = elts[2];
367   fail_unless(elt == 2476, "Improper copy (expected %d, got %d)", 2476, elt);
368 }
369 END_TEST
370 
START_TEST(append_arrays_test)371 START_TEST (append_arrays_test) {
372   array_header *a, *b, *res;
373   int elt, *elts;
374 
375   p = make_sub_pool(NULL);
376   a = make_array(p, 0, sizeof(int));
377   b = make_array(p, 0, sizeof(int));
378 
379   res = append_arrays(NULL, NULL, NULL);
380   fail_unless(res == NULL, "Failed to handle null arguments");
381   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
382 
383   res = append_arrays(p, NULL, NULL);
384   fail_unless(res == NULL, "Failed to handle null arguments");
385   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
386 
387   res = append_arrays(NULL, a, NULL);
388   fail_unless(res == NULL, "Failed to handle null arguments");
389   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
390 
391   res = append_arrays(NULL, NULL, b);
392   fail_unless(res == NULL, "Failed to handle null arguments");
393   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
394 
395   res = append_arrays(p, a, NULL);
396   fail_unless(res == NULL, "Failed to handle null arguments");
397   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
398 
399   res = append_arrays(p, NULL, b);
400   fail_unless(res == NULL, "Failed to handle null arguments");
401   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
402 
403   res = append_arrays(NULL, a, b);
404   fail_unless(res == NULL, "Failed to handle null arguments");
405   fail_unless(errno == EINVAL, "Failed to set errno to EINVAL");
406 
407   *((int *) push_array(a)) = -1;
408   *((int *) push_array(a)) = 2;
409   *((int *) push_array(b)) = 2476;
410   *((int *) push_array(b)) = 4762;
411   *((int *) push_array(b)) = 7642;
412 
413   res = append_arrays(p, a, b);
414 
415   fail_unless(res->elt_size == a->elt_size,
416     "Append item size wrong (expected %d, got %d)", a->elt_size, res->elt_size);
417   fail_unless(res->nelts == 5,
418     "Append nelts wrong (expected %d, got %d)", 5, res->nelts);
419 
420   fail_unless(res->nalloc == 8,
421     "Append nalloc wrong (expected %d, got %d)", 8, res->nalloc);
422 
423   elts = res->elts;
424 
425   elt = elts[0];
426   fail_unless(elt == -1, "Improper append (expected %d, got %d)", -1, elt);
427 
428   elt = elts[1];
429   fail_unless(elt == 2, "Improper append (expected %d, got %d)", 2, elt);
430 
431   elt = elts[2];
432   fail_unless(elt == 2476, "Improper append (expected %d, got %d)", 2476, elt);
433 
434   elt = elts[3];
435   fail_unless(elt == 4762, "Improper append (expected %d, got %d)", 4762, elt);
436 
437   elt = elts[4];
438   fail_unless(elt == 7642, "Improper append (expected %d, got %d)", 7642, elt);
439 }
440 END_TEST
441 
tests_get_array_suite(void)442 Suite *tests_get_array_suite(void) {
443   Suite *suite;
444   TCase *testcase;
445 
446   suite = suite_create("array");
447 
448   testcase = tcase_create("base");
449 
450   tcase_add_checked_fixture(testcase, set_up, tear_down);
451 
452   tcase_add_test(testcase, make_array_test);
453   tcase_add_test(testcase, push_array_test);
454   tcase_add_test(testcase, array_cat_test);
455   tcase_add_test(testcase, array_cat2_test);
456   tcase_add_test(testcase, clear_array_test);
457   tcase_add_test(testcase, copy_array_test);
458   tcase_add_test(testcase, copy_array_str_test);
459   tcase_add_test(testcase, copy_array_hdr_test);
460   tcase_add_test(testcase, append_arrays_test);
461 
462   suite_add_tcase(suite, testcase);
463 
464   return suite;
465 }
466