Home | History | Annotate | Line # | Download | only in test
      1 /*
      2  * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
      3  * Copyright (c) 2017, Oracle and/or its affiliates.  All rights reserved.
      4  *
      5  * Licensed under the OpenSSL license (the "License").  You may not use
      6  * this file except in compliance with the License.  You can obtain a copy
      7  * in the file LICENSE in the source distribution or at
      8  * https://www.openssl.org/source/license.html
      9  */
     10 
     11 #include <stdio.h>
     12 #include <string.h>
     13 
     14 #include <openssl/opensslconf.h>
     15 #include <openssl/safestack.h>
     16 #include <openssl/err.h>
     17 #include <openssl/crypto.h>
     18 
     19 #include "internal/nelem.h"
     20 #include "testutil.h"
     21 
     22 /* The macros below generate unused functions which error out one of the clang
     23  * builds.  We disable this check here.
     24  */
     25 #ifdef __clang__
     26 #pragma clang diagnostic ignored "-Wunused-function"
     27 #endif
     28 
     29 typedef struct {
     30     int n;
     31     char c;
     32 } SS;
     33 
     34 typedef union {
     35     int n;
     36     char c;
     37 } SU;
     38 
     39 DEFINE_SPECIAL_STACK_OF(sint, int)
     40 DEFINE_SPECIAL_STACK_OF_CONST(uchar, unsigned char)
     41 DEFINE_STACK_OF(SS)
     42 DEFINE_STACK_OF_CONST(SU)
     43 
     44 static int int_compare(const int *const *a, const int *const *b)
     45 {
     46     if (**a < **b)
     47         return -1;
     48     if (**a > **b)
     49         return 1;
     50     return 0;
     51 }
     52 
     53 static int test_int_stack(int reserve)
     54 {
     55     static int v[] = { 1, 2, -4, 16, 999, 1, -173, 1, 9 };
     56     static int notpresent = -1;
     57     const int n = OSSL_NELEM(v);
     58     static struct {
     59         int value;
     60         int unsorted;
     61         int sorted;
     62         int ex;
     63     } finds[] = {
     64         { 2,    1,  5,  5   },
     65         { 9,    7,  6,  6   },
     66         { -173, 5,  0,  0   },
     67         { 999,  3,  8,  8   },
     68         { 0,   -1, -1,  1   }
     69     };
     70     const int n_finds = OSSL_NELEM(finds);
     71     static struct {
     72         int value;
     73         int ex;
     74     } exfinds[] = {
     75         { 3,    5   },
     76         { 1000, 8   },
     77         { 20,   8   },
     78         { -999, 0   },
     79         { -5,   0   },
     80         { 8,    5   }
     81     };
     82     const int n_exfinds = OSSL_NELEM(exfinds);
     83     STACK_OF(sint) *s = sk_sint_new_null();
     84     int i;
     85     int testresult = 0;
     86 
     87     if (!TEST_ptr(s)
     88         || (reserve > 0 && !TEST_true(sk_sint_reserve(s, 5 * reserve))))
     89         goto end;
     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(int reserve)
    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     if (!TEST_ptr(s)
    183         || (reserve > 0 && !TEST_true(sk_uchar_reserve(s, 5 * reserve))))
    184         goto end;
    185 
    186     /* unshift and num */
    187     for (i = 0; i < n; i++) {
    188         if (!TEST_int_eq(sk_uchar_num(s), i)) {
    189             TEST_info("uchar stack size %d", i);
    190             goto end;
    191         }
    192         sk_uchar_unshift(s, v + i);
    193     }
    194     if (!TEST_int_eq(sk_uchar_num(s), n))
    195         goto end;
    196 
    197     /* dup */
    198     r = sk_uchar_dup(s);
    199     if (!TEST_int_eq(sk_uchar_num(r), n))
    200         goto end;
    201     sk_uchar_sort(r);
    202 
    203     /* pop */
    204     for (i = 0; i < n; i++)
    205         if (!TEST_ptr_eq(sk_uchar_pop(s), v + i)) {
    206             TEST_info("uchar pop %d", i);
    207             goto end;
    208         }
    209 
    210     /* free -- we rely on the debug malloc to detect leakage here */
    211     sk_uchar_free(s);
    212     s = NULL;
    213 
    214     /* dup again */
    215     if (!TEST_int_eq(sk_uchar_num(r), n))
    216         goto end;
    217 
    218     /* zero */
    219     sk_uchar_zero(r);
    220     if (!TEST_int_eq(sk_uchar_num(r), 0))
    221         goto end;
    222 
    223     /* insert */
    224     sk_uchar_insert(r, v, 0);
    225     sk_uchar_insert(r, v + 2, -1);
    226     sk_uchar_insert(r, v + 1, 1);
    227     for (i = 0; i < 3; i++)
    228         if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
    229             TEST_info("uchar insert %d", i);
    230             goto end;
    231         }
    232 
    233     /* delete */
    234     if (!TEST_ptr_null(sk_uchar_delete(r, 12)))
    235         goto end;
    236     if (!TEST_ptr_eq(sk_uchar_delete(r, 1), v + 1))
    237         goto end;
    238 
    239     /* set */
    240     sk_uchar_set(r, 1, v + 1);
    241     for (i = 0; i < 2; i++)
    242         if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
    243             TEST_info("uchar set %d", i);
    244             goto end;
    245         }
    246 
    247     testresult = 1;
    248 end:
    249     sk_uchar_free(r);
    250     sk_uchar_free(s);
    251     return testresult;
    252 }
    253 
    254 static SS *SS_copy(const SS *p)
    255 {
    256     SS *q = OPENSSL_malloc(sizeof(*q));
    257 
    258     if (q != NULL)
    259         memcpy(q, p, sizeof(*q));
    260     return q;
    261 }
    262 
    263 static void SS_free(SS *p) {
    264     OPENSSL_free(p);
    265 }
    266 
    267 static int test_SS_stack(void)
    268 {
    269     STACK_OF(SS) *s = sk_SS_new_null();
    270     STACK_OF(SS) *r = NULL;
    271     SS *v[10], *p;
    272     const int n = OSSL_NELEM(v);
    273     int i;
    274     int testresult = 0;
    275 
    276     /* allocate and push */
    277     for (i = 0; i < n; i++) {
    278         v[i] = OPENSSL_malloc(sizeof(*v[i]));
    279 
    280         if (!TEST_ptr(v[i]))
    281             goto end;
    282         v[i]->n = i;
    283         v[i]->c = 'A' + i;
    284         if (!TEST_int_eq(sk_SS_num(s), i)) {
    285             TEST_info("SS stack size %d", i);
    286             goto end;
    287         }
    288         sk_SS_push(s, v[i]);
    289     }
    290     if (!TEST_int_eq(sk_SS_num(s), n))
    291         goto end;
    292 
    293     /* deepcopy */
    294     r = sk_SS_deep_copy(s, &SS_copy, &SS_free);
    295     if (!TEST_ptr(r))
    296         goto end;
    297     for (i = 0; i < n; i++) {
    298         p = sk_SS_value(r, i);
    299         if (!TEST_ptr_ne(p, v[i])) {
    300             TEST_info("SS deepcopy non-copy %d", i);
    301             goto end;
    302         }
    303         if (!TEST_int_eq(p->n, v[i]->n)) {
    304             TEST_info("test SS deepcopy int %d", i);
    305             goto end;
    306         }
    307         if (!TEST_char_eq(p->c, v[i]->c)) {
    308             TEST_info("SS deepcopy char %d", i);
    309             goto end;
    310         }
    311     }
    312 
    313     /* pop_free - we rely on the malloc debug to catch the leak */
    314     sk_SS_pop_free(r, &SS_free);
    315     r = NULL;
    316 
    317     /* delete_ptr */
    318     p = sk_SS_delete_ptr(s, v[3]);
    319     if (!TEST_ptr(p))
    320         goto end;
    321     SS_free(p);
    322     if (!TEST_int_eq(sk_SS_num(s), n - 1))
    323         goto end;
    324     for (i = 0; i < n-1; i++)
    325         if (!TEST_ptr_eq(sk_SS_value(s, i), v[i<3 ? i : 1+i])) {
    326             TEST_info("SS delete ptr item %d", i);
    327             goto end;
    328         }
    329 
    330     testresult = 1;
    331 end:
    332     sk_SS_pop_free(r, &SS_free);
    333     sk_SS_pop_free(s, &SS_free);
    334     return testresult;
    335 }
    336 
    337 static int test_SU_stack(void)
    338 {
    339     STACK_OF(SU) *s = sk_SU_new_null();
    340     SU v[10];
    341     const int n = OSSL_NELEM(v);
    342     int i;
    343     int testresult = 0;
    344 
    345     /* allocate and push */
    346     for (i = 0; i < n; i++) {
    347         if ((i & 1) == 0)
    348             v[i].n = i;
    349         else
    350             v[i].c = 'A' + i;
    351         if (!TEST_int_eq(sk_SU_num(s), i)) {
    352             TEST_info("SU stack size %d", i);
    353             goto end;
    354         }
    355         sk_SU_push(s, v + i);
    356     }
    357     if (!TEST_int_eq(sk_SU_num(s), n))
    358         goto end;
    359 
    360     /* check the pointers are correct */
    361     for (i = 0; i < n; i++)
    362         if (!TEST_ptr_eq(sk_SU_value(s, i),  v + i)) {
    363             TEST_info("SU pointer check %d", i);
    364             goto end;
    365         }
    366 
    367     testresult = 1;
    368 end:
    369     sk_SU_free(s);
    370     return testresult;
    371 }
    372 
    373 int setup_tests(void)
    374 {
    375     ADD_ALL_TESTS(test_int_stack, 4);
    376     ADD_ALL_TESTS(test_uchar_stack, 4);
    377     ADD_TEST(test_SS_stack);
    378     ADD_TEST(test_SU_stack);
    379     return 1;
    380 }
    381