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