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