123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380 |
- /*
- * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved.
- * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
- *
- * Licensed under the Apache License 2.0 (the "License"). You may not use
- * this file except in compliance with the License. You can obtain a copy
- * in the file LICENSE in the source distribution or at
- * https://www.openssl.org/source/license.html
- */
- #include <stdio.h>
- #include <string.h>
- #include <openssl/opensslconf.h>
- #include <openssl/safestack.h>
- #include <openssl/err.h>
- #include <openssl/crypto.h>
- #include "internal/nelem.h"
- #include "testutil.h"
- /* The macros below generate unused functions which error out one of the clang
- * builds. We disable this check here.
- */
- #ifdef __clang__
- #pragma clang diagnostic ignored "-Wunused-function"
- #endif
- typedef struct {
- int n;
- char c;
- } SS;
- typedef union {
- int n;
- char c;
- } SU;
- DEFINE_SPECIAL_STACK_OF(sint, int)
- DEFINE_SPECIAL_STACK_OF_CONST(uchar, unsigned char)
- DEFINE_STACK_OF(SS)
- DEFINE_STACK_OF_CONST(SU)
- static int int_compare(const int *const *a, const int *const *b)
- {
- if (**a < **b)
- return -1;
- if (**a > **b)
- return 1;
- return 0;
- }
- static int test_int_stack(int reserve)
- {
- static int v[] = { 1, 2, -4, 16, 999, 1, -173, 1, 9 };
- static int notpresent = -1;
- const int n = OSSL_NELEM(v);
- static struct {
- int value;
- int unsorted;
- int sorted;
- int ex;
- } finds[] = {
- { 2, 1, 5, 5 },
- { 9, 7, 6, 6 },
- { -173, 5, 0, 0 },
- { 999, 3, 8, 8 },
- { 0, -1, -1, 1 }
- };
- const int n_finds = OSSL_NELEM(finds);
- static struct {
- int value;
- int ex;
- } exfinds[] = {
- { 3, 5 },
- { 1000, 8 },
- { 20, 8 },
- { -999, 0 },
- { -5, 0 },
- { 8, 5 }
- };
- const int n_exfinds = OSSL_NELEM(exfinds);
- STACK_OF(sint) *s = sk_sint_new_null();
- int i;
- int testresult = 0;
- if (!TEST_ptr(s)
- || (reserve > 0 && !TEST_true(sk_sint_reserve(s, 5 * reserve))))
- goto end;
- /* Check push and num */
- for (i = 0; i < n; i++) {
- if (!TEST_int_eq(sk_sint_num(s), i)) {
- TEST_info("int stack size %d", i);
- goto end;
- }
- sk_sint_push(s, v + i);
- }
- if (!TEST_int_eq(sk_sint_num(s), n))
- goto end;
- /* check the values */
- for (i = 0; i < n; i++)
- if (!TEST_ptr_eq(sk_sint_value(s, i), v + i)) {
- TEST_info("int value %d", i);
- goto end;
- }
- /* find unsorted -- the pointers are compared */
- for (i = 0; i < n_finds; i++) {
- int *val = (finds[i].unsorted == -1) ? ¬present
- : v + finds[i].unsorted;
- if (!TEST_int_eq(sk_sint_find(s, val), finds[i].unsorted)) {
- TEST_info("int unsorted find %d", i);
- goto end;
- }
- }
- /* find_ex unsorted */
- for (i = 0; i < n_finds; i++) {
- int *val = (finds[i].unsorted == -1) ? ¬present
- : v + finds[i].unsorted;
- if (!TEST_int_eq(sk_sint_find_ex(s, val), finds[i].unsorted)) {
- TEST_info("int unsorted find_ex %d", i);
- goto end;
- }
- }
- /* sorting */
- if (!TEST_false(sk_sint_is_sorted(s)))
- goto end;
- (void)sk_sint_set_cmp_func(s, &int_compare);
- sk_sint_sort(s);
- if (!TEST_true(sk_sint_is_sorted(s)))
- goto end;
- /* find sorted -- the value is matched so we don't need to locate it */
- for (i = 0; i < n_finds; i++)
- if (!TEST_int_eq(sk_sint_find(s, &finds[i].value), finds[i].sorted)) {
- TEST_info("int sorted find %d", i);
- goto end;
- }
- /* find_ex sorted */
- for (i = 0; i < n_finds; i++)
- if (!TEST_int_eq(sk_sint_find_ex(s, &finds[i].value), finds[i].ex)) {
- TEST_info("int sorted find_ex present %d", i);
- goto end;
- }
- for (i = 0; i < n_exfinds; i++)
- if (!TEST_int_eq(sk_sint_find_ex(s, &exfinds[i].value), exfinds[i].ex)){
- TEST_info("int sorted find_ex absent %d", i);
- goto end;
- }
- /* shift */
- if (!TEST_ptr_eq(sk_sint_shift(s), v + 6))
- goto end;
- testresult = 1;
- end:
- sk_sint_free(s);
- return testresult;
- }
- static int uchar_compare(const unsigned char *const *a,
- const unsigned char *const *b)
- {
- return **a - (signed int)**b;
- }
- static int test_uchar_stack(int reserve)
- {
- static const unsigned char v[] = { 1, 3, 7, 5, 255, 0 };
- const int n = OSSL_NELEM(v);
- STACK_OF(uchar) *s = sk_uchar_new(&uchar_compare), *r = NULL;
- int i;
- int testresult = 0;
- if (!TEST_ptr(s)
- || (reserve > 0 && !TEST_true(sk_uchar_reserve(s, 5 * reserve))))
- goto end;
- /* unshift and num */
- for (i = 0; i < n; i++) {
- if (!TEST_int_eq(sk_uchar_num(s), i)) {
- TEST_info("uchar stack size %d", i);
- goto end;
- }
- sk_uchar_unshift(s, v + i);
- }
- if (!TEST_int_eq(sk_uchar_num(s), n))
- goto end;
- /* dup */
- r = sk_uchar_dup(s);
- if (!TEST_int_eq(sk_uchar_num(r), n))
- goto end;
- sk_uchar_sort(r);
- /* pop */
- for (i = 0; i < n; i++)
- if (!TEST_ptr_eq(sk_uchar_pop(s), v + i)) {
- TEST_info("uchar pop %d", i);
- goto end;
- }
- /* free -- we rely on the debug malloc to detect leakage here */
- sk_uchar_free(s);
- s = NULL;
- /* dup again */
- if (!TEST_int_eq(sk_uchar_num(r), n))
- goto end;
- /* zero */
- sk_uchar_zero(r);
- if (!TEST_int_eq(sk_uchar_num(r), 0))
- goto end;
- /* insert */
- sk_uchar_insert(r, v, 0);
- sk_uchar_insert(r, v + 2, -1);
- sk_uchar_insert(r, v + 1, 1);
- for (i = 0; i < 3; i++)
- if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
- TEST_info("uchar insert %d", i);
- goto end;
- }
- /* delete */
- if (!TEST_ptr_null(sk_uchar_delete(r, 12)))
- goto end;
- if (!TEST_ptr_eq(sk_uchar_delete(r, 1), v + 1))
- goto end;
- /* set */
- (void)sk_uchar_set(r, 1, v + 1);
- for (i = 0; i < 2; i++)
- if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
- TEST_info("uchar set %d", i);
- goto end;
- }
- testresult = 1;
- end:
- sk_uchar_free(r);
- sk_uchar_free(s);
- return testresult;
- }
- static SS *SS_copy(const SS *p)
- {
- SS *q = OPENSSL_malloc(sizeof(*q));
- if (q != NULL)
- memcpy(q, p, sizeof(*q));
- return q;
- }
- static void SS_free(SS *p) {
- OPENSSL_free(p);
- }
- static int test_SS_stack(void)
- {
- STACK_OF(SS) *s = sk_SS_new_null();
- STACK_OF(SS) *r = NULL;
- SS *v[10], *p;
- const int n = OSSL_NELEM(v);
- int i;
- int testresult = 0;
- /* allocate and push */
- for (i = 0; i < n; i++) {
- v[i] = OPENSSL_malloc(sizeof(*v[i]));
- if (!TEST_ptr(v[i]))
- goto end;
- v[i]->n = i;
- v[i]->c = 'A' + i;
- if (!TEST_int_eq(sk_SS_num(s), i)) {
- TEST_info("SS stack size %d", i);
- goto end;
- }
- sk_SS_push(s, v[i]);
- }
- if (!TEST_int_eq(sk_SS_num(s), n))
- goto end;
- /* deepcopy */
- r = sk_SS_deep_copy(s, &SS_copy, &SS_free);
- if (!TEST_ptr(r))
- goto end;
- for (i = 0; i < n; i++) {
- p = sk_SS_value(r, i);
- if (!TEST_ptr_ne(p, v[i])) {
- TEST_info("SS deepcopy non-copy %d", i);
- goto end;
- }
- if (!TEST_int_eq(p->n, v[i]->n)) {
- TEST_info("test SS deepcopy int %d", i);
- goto end;
- }
- if (!TEST_char_eq(p->c, v[i]->c)) {
- TEST_info("SS deepcopy char %d", i);
- goto end;
- }
- }
- /* pop_free - we rely on the malloc debug to catch the leak */
- sk_SS_pop_free(r, &SS_free);
- r = NULL;
- /* delete_ptr */
- p = sk_SS_delete_ptr(s, v[3]);
- if (!TEST_ptr(p))
- goto end;
- SS_free(p);
- if (!TEST_int_eq(sk_SS_num(s), n - 1))
- goto end;
- for (i = 0; i < n-1; i++)
- if (!TEST_ptr_eq(sk_SS_value(s, i), v[i<3 ? i : 1+i])) {
- TEST_info("SS delete ptr item %d", i);
- goto end;
- }
- testresult = 1;
- end:
- sk_SS_pop_free(r, &SS_free);
- sk_SS_pop_free(s, &SS_free);
- return testresult;
- }
- static int test_SU_stack(void)
- {
- STACK_OF(SU) *s = sk_SU_new_null();
- SU v[10];
- const int n = OSSL_NELEM(v);
- int i;
- int testresult = 0;
- /* allocate and push */
- for (i = 0; i < n; i++) {
- if ((i & 1) == 0)
- v[i].n = i;
- else
- v[i].c = 'A' + i;
- if (!TEST_int_eq(sk_SU_num(s), i)) {
- TEST_info("SU stack size %d", i);
- goto end;
- }
- sk_SU_push(s, v + i);
- }
- if (!TEST_int_eq(sk_SU_num(s), n))
- goto end;
- /* check the pointers are correct */
- for (i = 0; i < n; i++)
- if (!TEST_ptr_eq(sk_SU_value(s, i), v + i)) {
- TEST_info("SU pointer check %d", i);
- goto end;
- }
- testresult = 1;
- end:
- sk_SU_free(s);
- return testresult;
- }
- int setup_tests(void)
- {
- ADD_ALL_TESTS(test_int_stack, 4);
- ADD_ALL_TESTS(test_uchar_stack, 4);
- ADD_TEST(test_SS_stack);
- ADD_TEST(test_SU_stack);
- return 1;
- }
|