List undocumented macros
[openssl.git] / test / stack_test.c
1 /*
2  * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 /* ====================================================================
11  * Copyright (c) 2017 Oracle and/or its affiliates.  All rights reserved.
12  */
13
14 #include <stdio.h>
15 #include <string.h>
16
17 #include <openssl/opensslconf.h>
18 #include <openssl/safestack.h>
19 #include <openssl/err.h>
20 #include <openssl/crypto.h>
21
22 #include "e_os.h"
23 #include "testutil.h"
24
25 /* The macros below generate unused functions which error out one of the clang
26  * builds.  We disable this check here.
27  */
28 #ifdef __clang__
29 #pragma clang diagnostic ignored "-Wunused-function"
30 #endif
31
32 typedef struct {
33     int n;
34     char c;
35 } SS;
36
37 typedef union {
38     int n;
39     char c;
40 } SU;
41
42 DEFINE_SPECIAL_STACK_OF(sint, int)
43 DEFINE_SPECIAL_STACK_OF_CONST(uchar, unsigned char)
44 DEFINE_STACK_OF(SS)
45 DEFINE_STACK_OF_CONST(SU)
46
47 static int int_compare(const int *const *a, const int *const *b)
48 {
49     if (**a < **b)
50         return -1;
51     if (**a > **b)
52         return 1;
53     return 0;
54 }
55
56 static int test_int_stack(void)
57 {
58     static int v[] = { 1, 2, -4, 16, 999, 1, -173, 1, 9 };
59     static int notpresent = -1;
60     const int n = OSSL_NELEM(v);
61     static struct {
62         int value;
63         int unsorted;
64         int sorted;
65         int ex;
66     } finds[] = {
67         { 2,    1,  5,  5   },
68         { 9,    7,  6,  6   },
69         { -173, 5,  0,  0   },
70         { 999,  3,  8,  8   },
71         { 0,   -1, -1,  1   }
72     };
73     const int n_finds = OSSL_NELEM(finds);
74     static struct {
75         int value;
76         int ex;
77     } exfinds[] = {
78         { 3,    5   },
79         { 1000, 8   },
80         { 20,   8   },
81         { -999, 0   },
82         { -5,   0   },
83         { 8,    5   }
84     };
85     const int n_exfinds = OSSL_NELEM(exfinds);
86     STACK_OF(sint) *s = sk_sint_new_null();
87     int i;
88     int testresult = 0;
89
90     /* Check push and num */
91     for (i = 0; i < n; i++) {
92         if (!TEST_int_eq(sk_sint_num(s), i)) {
93             TEST_info("int stack size %d", i);
94             goto end;
95         }
96         sk_sint_push(s, v + i);
97     }
98     if (!TEST_int_eq(sk_sint_num(s), n))
99         goto end;
100
101     /* check the values */
102     for (i = 0; i < n; i++)
103         if (!TEST_ptr_eq(sk_sint_value(s, i), v + i)) {
104             TEST_info("int value %d", i);
105             goto end;
106         }
107
108     /* find unsorted -- the pointers are compared */
109     for (i = 0; i < n_finds; i++) {
110         int *val = (finds[i].unsorted == -1) ? &notpresent
111                                              : v + finds[i].unsorted;
112
113         if (!TEST_int_eq(sk_sint_find(s, val), finds[i].unsorted)) {
114             TEST_info("int unsorted find %d", i);
115             goto end;
116         }
117     }
118
119     /* find_ex unsorted */
120     for (i = 0; i < n_finds; i++) {
121         int *val = (finds[i].unsorted == -1) ? &notpresent
122                                              : v + finds[i].unsorted;
123
124         if (!TEST_int_eq(sk_sint_find_ex(s, val), finds[i].unsorted)) {
125             TEST_info("int unsorted find_ex %d", i);
126             goto end;
127         }
128     }
129
130     /* sorting */
131     if (!TEST_false(sk_sint_is_sorted(s)))
132         goto end;
133     sk_sint_set_cmp_func(s, &int_compare);
134     sk_sint_sort(s);
135     if (!TEST_true(sk_sint_is_sorted(s)))
136         goto end;
137
138     /* find sorted -- the value is matched so we don't need to locate it */
139     for (i = 0; i < n_finds; i++)
140         if (!TEST_int_eq(sk_sint_find(s, &finds[i].value), finds[i].sorted)) {
141             TEST_info("int sorted find %d", i);
142             goto end;
143         }
144
145     /* find_ex sorted */
146     for (i = 0; i < n_finds; i++)
147         if (!TEST_int_eq(sk_sint_find_ex(s, &finds[i].value), finds[i].ex)) {
148             TEST_info("int sorted find_ex present %d", i);
149             goto end;
150         }
151     for (i = 0; i < n_exfinds; i++)
152         if (!TEST_int_eq(sk_sint_find_ex(s, &exfinds[i].value), exfinds[i].ex)){
153             TEST_info("int sorted find_ex absent %d", i);
154             goto end;
155         }
156
157     /* shift */
158     if (!TEST_ptr_eq(sk_sint_shift(s), v + 6))
159         goto end;
160
161     testresult = 1;
162 end:
163     sk_sint_free(s);
164     return testresult;
165 }
166
167 static int uchar_compare(const unsigned char *const *a,
168                          const unsigned char *const *b)
169 {
170     return **a - (signed int)**b;
171 }
172
173 static int test_uchar_stack(void)
174 {
175     static const unsigned char v[] = { 1, 3, 7, 5, 255, 0 };
176     const int n = OSSL_NELEM(v);
177     STACK_OF(uchar) *s = sk_uchar_new(&uchar_compare), *r = NULL;
178     int i;
179     int testresult = 0;
180
181     /* unshift and num */
182     for (i = 0; i < n; i++) {
183         if (!TEST_int_eq(sk_uchar_num(s), i)) {
184             TEST_info("uchar stack size %d", i);
185             goto end;
186         }
187         sk_uchar_unshift(s, v + i);
188     }
189     if (!TEST_int_eq(sk_uchar_num(s), n))
190         goto end;
191
192     /* dup */
193     r = sk_uchar_dup(s);
194     if (!TEST_int_eq(sk_uchar_num(r), n))
195         goto end;
196     sk_uchar_sort(r);
197
198     /* pop */
199     for (i = 0; i < n; i++) 
200         if (!TEST_ptr_eq(sk_uchar_pop(s), v + i)) {
201             TEST_info("uchar pop %d", i);
202             goto end;
203         }
204
205     /* free -- we rely on the debug malloc to detect leakage here */
206     sk_uchar_free(s);
207     s = NULL;
208
209     /* dup again */
210     if (!TEST_int_eq(sk_uchar_num(r), n))
211         goto end;
212
213     /* zero */
214     sk_uchar_zero(r);
215     if (!TEST_int_eq(sk_uchar_num(r), 0))
216         goto end;
217
218     /* insert */
219     sk_uchar_insert(r, v, 0);
220     sk_uchar_insert(r, v + 2, -1);
221     sk_uchar_insert(r, v + 1, 1);
222     for (i = 0; i < 3; i++)
223         if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
224             TEST_info("uchar insert %d", i);
225             goto end;
226         }
227
228     /* delete */
229     if (!TEST_ptr_null(sk_uchar_delete(r, 12)))
230         goto end;
231     if (!TEST_ptr_eq(sk_uchar_delete(r, 1), v + 1))
232         goto end;
233
234     /* set */
235     sk_uchar_set(r, 1, v + 1);
236     for (i = 0; i < 2; i++)
237         if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
238             TEST_info("uchar set %d", i);
239             goto end;
240         }
241
242     testresult = 1;
243 end:
244     sk_uchar_free(r);
245     sk_uchar_free(s);
246     return testresult;
247 }
248
249 static SS *SS_copy(const SS *p)
250 {
251     SS *q = OPENSSL_malloc(sizeof(*q));
252
253     if (q != NULL)
254         memcpy(q, p, sizeof(*q));
255     return q;
256 }
257
258 static void SS_free(SS *p) {
259     OPENSSL_free(p);
260 }
261
262 static int test_SS_stack(void)
263 {
264     STACK_OF(SS) *s = sk_SS_new_null();
265     STACK_OF(SS) *r = NULL;
266     SS *v[10], *p;
267     const int n = OSSL_NELEM(v);
268     int i;
269     int testresult = 0;
270
271     /* allocate and push */
272     for (i = 0; i < n; i++) {
273         v[i] = OPENSSL_malloc(sizeof(*v[i]));
274
275         if (!TEST_ptr(v[i]))
276             goto end;
277         v[i]->n = i;
278         v[i]->c = 'A' + i;
279         if (!TEST_int_eq(sk_SS_num(s), i)) {
280             TEST_info("SS stack size %d", i);
281             goto end;
282         }
283         sk_SS_push(s, v[i]);
284     }
285     if (!TEST_int_eq(sk_SS_num(s), n))
286         goto end;
287
288     /* deepcopy */
289     r = sk_SS_deep_copy(s, &SS_copy, &SS_free);
290     if (!TEST_ptr(r))
291         goto end;
292     for (i = 0; i < n; i++) {
293         p = sk_SS_value(r, i);
294         if (!TEST_ptr_ne(p, v[i])) {
295             TEST_info("SS deepcopy non-copy %d", i);
296             goto end;
297         }
298         if (!TEST_int_eq(p->n, v[i]->n)) {
299             TEST_info("test SS deepcopy int %d", i);
300             goto end;
301         }
302         if (!TEST_char_eq(p->c, v[i]->c)) {
303             TEST_info("SS deepcopy char %d", i);
304             goto end;
305         }
306     }
307
308     /* pop_free - we rely on the malloc debug to catch the leak */
309     sk_SS_pop_free(r, &SS_free);
310     r = NULL;
311
312     /* delete_ptr */
313     p = sk_SS_delete_ptr(s, v[3]);
314     if (!TEST_ptr(p))
315         goto end;
316     SS_free(p);
317     if (!TEST_int_eq(sk_SS_num(s), n - 1))
318         goto end;
319     for (i = 0; i < n-1; i++)
320         if (!TEST_ptr_eq(sk_SS_value(s, i), v[i<3 ? i : 1+i])) {
321             TEST_info("SS delete ptr item %d", i);
322             goto end;
323         }
324
325     testresult = 1;
326 end:
327     sk_SS_pop_free(r, &SS_free);
328     sk_SS_pop_free(s, &SS_free);
329     return testresult;
330 }
331
332 static int test_SU_stack(void)
333 {
334     STACK_OF(SU) *s = sk_SU_new_null();
335     SU v[10];
336     const int n = OSSL_NELEM(v);
337     int i;
338     int testresult = 0;
339
340     /* allocate and push */
341     for (i = 0; i < n; i++) {
342         if ((i & 1) == 0)
343             v[i].n = i;
344         else
345             v[i].c = 'A' + i;
346         if (!TEST_int_eq(sk_SU_num(s), i)) {
347             TEST_info("SU stack size %d", i);
348             goto end;
349         }
350         sk_SU_push(s, v + i);
351     }
352     if (!TEST_int_eq(sk_SU_num(s), n))
353         goto end;
354
355     /* check the pointers are correct */
356     for (i = 0; i < n; i++)
357         if (!TEST_ptr_eq(sk_SU_value(s, i),  v + i)) {
358             TEST_info("SU pointer check %d", i);
359             goto end;
360         }
361
362     testresult = 1;
363 end:
364     sk_SU_free(s);
365     return testresult;
366 }
367
368 void register_tests(void)
369 {
370     ADD_TEST(test_int_stack);
371     ADD_TEST(test_uchar_stack);
372     ADD_TEST(test_SS_stack);
373     ADD_TEST(test_SU_stack);
374 }