diff options
Diffstat (limited to 'crypto/stack/stack.c')
| -rw-r--r-- | crypto/stack/stack.c | 155 |
1 files changed, 110 insertions, 45 deletions
diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c index 975515db5972..51080b876797 100644 --- a/crypto/stack/stack.c +++ b/crypto/stack/stack.c @@ -1,7 +1,7 @@ /* - * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved. * - * Licensed under the OpenSSL license (the "License"). You may not use + * 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 @@ -11,7 +11,6 @@ #include "internal/cryptlib.h" #include "internal/numbers.h" #include <openssl/stack.h> -#include <openssl/objects.h> #include <errno.h> #include <openssl/e_os2.h> /* For ossl_inline */ @@ -20,8 +19,7 @@ */ static const int min_nodes = 4; static const int max_nodes = SIZE_MAX / sizeof(void *) < INT_MAX - ? (int)(SIZE_MAX / sizeof(void *)) - : INT_MAX; + ? (int)(SIZE_MAX / sizeof(void *)) : INT_MAX; struct stack_st { int num; @@ -31,7 +29,8 @@ struct stack_st { OPENSSL_sk_compfunc comp; }; -OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, OPENSSL_sk_compfunc c) +OPENSSL_sk_compfunc OPENSSL_sk_set_cmp_func(OPENSSL_STACK *sk, + OPENSSL_sk_compfunc c) { OPENSSL_sk_compfunc old = sk->comp; @@ -46,46 +45,58 @@ OPENSSL_STACK *OPENSSL_sk_dup(const OPENSSL_STACK *sk) { OPENSSL_STACK *ret; - if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_SK_DUP, ERR_R_MALLOC_FAILURE); - return NULL; - } + if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) + goto err; - /* direct structure assignment */ - *ret = *sk; + if (sk == NULL) { + ret->num = 0; + ret->sorted = 0; + ret->comp = NULL; + } else { + /* direct structure assignment */ + *ret = *sk; + } - if (sk->num == 0) { + if (sk == NULL || sk->num == 0) { /* postpone |ret->data| allocation */ ret->data = NULL; ret->num_alloc = 0; return ret; } + /* duplicate |sk->data| content */ - if ((ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc)) == NULL) + ret->data = OPENSSL_malloc(sizeof(*ret->data) * sk->num_alloc); + if (ret->data == NULL) goto err; memcpy(ret->data, sk->data, sizeof(void *) * sk->num); return ret; + err: + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); OPENSSL_sk_free(ret); return NULL; } OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, - OPENSSL_sk_copyfunc copy_func, - OPENSSL_sk_freefunc free_func) + OPENSSL_sk_copyfunc copy_func, + OPENSSL_sk_freefunc free_func) { OPENSSL_STACK *ret; int i; - if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) { - CRYPTOerr(CRYPTO_F_OPENSSL_SK_DEEP_COPY, ERR_R_MALLOC_FAILURE); - return NULL; - } + if ((ret = OPENSSL_malloc(sizeof(*ret))) == NULL) + goto err; - /* direct structure assignment */ - *ret = *sk; + if (sk == NULL) { + ret->num = 0; + ret->sorted = 0; + ret->comp = NULL; + } else { + /* direct structure assignment */ + *ret = *sk; + } - if (sk->num == 0) { + if (sk == NULL || sk->num == 0) { /* postpone |ret| data allocation */ ret->data = NULL; ret->num_alloc = 0; @@ -94,10 +105,8 @@ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, ret->num_alloc = sk->num > min_nodes ? sk->num : min_nodes; ret->data = OPENSSL_zalloc(sizeof(*ret->data) * ret->num_alloc); - if (ret->data == NULL) { - OPENSSL_free(ret); - return NULL; - } + if (ret->data == NULL) + goto err; for (i = 0; i < ret->num; ++i) { if (sk->data[i] == NULL) @@ -106,11 +115,15 @@ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, while (--i >= 0) if (ret->data[i] != NULL) free_func((void *)ret->data[i]); - OPENSSL_sk_free(ret); - return NULL; + goto err; } } return ret; + + err: + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); + OPENSSL_sk_free(ret); + return NULL; } OPENSSL_STACK *OPENSSL_sk_new_null(void) @@ -163,8 +176,10 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact) int num_alloc; /* Check to see the reservation isn't exceeding the hard limit */ - if (n > max_nodes - st->num) + if (n > max_nodes - st->num) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS); return 0; + } /* Figure out the new size */ num_alloc = st->num + n; @@ -178,7 +193,7 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact) * so |num_alloc| value is |n| or |min_nodes| if greater than |n|. */ if ((st->data = OPENSSL_zalloc(sizeof(void *) * num_alloc)) == NULL) { - CRYPTOerr(CRYPTO_F_SK_RESERVE, ERR_R_MALLOC_FAILURE); + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; } st->num_alloc = num_alloc; @@ -189,15 +204,19 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact) if (num_alloc <= st->num_alloc) return 1; num_alloc = compute_growth(num_alloc, st->num_alloc); - if (num_alloc == 0) + if (num_alloc == 0) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS); return 0; + } } else if (num_alloc == st->num_alloc) { return 1; } tmpdata = OPENSSL_realloc((void *)st->data, sizeof(void *) * num_alloc); - if (tmpdata == NULL) + if (tmpdata == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return 0; + } st->data = tmpdata; st->num_alloc = num_alloc; @@ -208,8 +227,10 @@ OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n) { OPENSSL_STACK *st = OPENSSL_zalloc(sizeof(OPENSSL_STACK)); - if (st == NULL) + if (st == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_MALLOC_FAILURE); return NULL; + } st->comp = c; @@ -226,8 +247,10 @@ OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n) int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n) { - if (st == NULL) + if (st == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); return 0; + } if (n < 0) return 1; @@ -236,8 +259,14 @@ int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n) int OPENSSL_sk_insert(OPENSSL_STACK *st, const void *data, int loc) { - if (st == NULL || st->num == max_nodes) + if (st == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + if (st->num == max_nodes) { + ERR_raise(ERR_LIB_CRYPTO, CRYPTO_R_TOO_MANY_RECORDS); return 0; + } if (!sk_reserve(st, 1, 0)) return 0; @@ -259,8 +288,8 @@ static ossl_inline void *internal_delete(OPENSSL_STACK *st, int loc) const void *ret = st->data[loc]; if (loc != st->num - 1) - memmove(&st->data[loc], &st->data[loc + 1], - sizeof(st->data[0]) * (st->num - loc - 1)); + memmove(&st->data[loc], &st->data[loc + 1], + sizeof(st->data[0]) * (st->num - loc - 1)); st->num--; return (void *)ret; @@ -270,6 +299,9 @@ void *OPENSSL_sk_delete_ptr(OPENSSL_STACK *st, const void *p) { int i; + if (st == NULL) + return NULL; + for (i = 0; i < st->num; i++) if (st->data[i] == p) return internal_delete(st, i); @@ -285,7 +317,7 @@ void *OPENSSL_sk_delete(OPENSSL_STACK *st, int loc) } static int internal_find(OPENSSL_STACK *st, const void *data, - int ret_val_options) + int ret_val_options, int *pnum) { const void *r; int i; @@ -295,8 +327,13 @@ static int internal_find(OPENSSL_STACK *st, const void *data, if (st->comp == NULL) { for (i = 0; i < st->num; i++) - if (st->data[i] == data) + if (st->data[i] == data) { + if (pnum != NULL) + *pnum = 1; return i; + } + if (pnum != NULL) + *pnum = 0; return -1; } @@ -307,20 +344,41 @@ static int internal_find(OPENSSL_STACK *st, const void *data, } if (data == NULL) return -1; - r = OBJ_bsearch_ex_(&data, st->data, st->num, sizeof(void *), st->comp, - ret_val_options); + if (pnum != NULL) + ret_val_options |= OSSL_BSEARCH_FIRST_VALUE_ON_MATCH; + r = ossl_bsearch(&data, st->data, st->num, sizeof(void *), st->comp, + ret_val_options); + + if (pnum != NULL) { + *pnum = 0; + if (r != NULL) { + const void **p = (const void **)r; + + while (p < st->data + st->num) { + if (st->comp(&data, p) != 0) + break; + ++*pnum; + ++p; + } + } + } return r == NULL ? -1 : (int)((const void **)r - st->data); } int OPENSSL_sk_find(OPENSSL_STACK *st, const void *data) { - return internal_find(st, data, OBJ_BSEARCH_FIRST_VALUE_ON_MATCH); + return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH, NULL); } int OPENSSL_sk_find_ex(OPENSSL_STACK *st, const void *data) { - return internal_find(st, data, OBJ_BSEARCH_VALUE_ON_NOMATCH); + return internal_find(st, data, OSSL_BSEARCH_VALUE_ON_NOMATCH, NULL); +} + +int OPENSSL_sk_find_all(OPENSSL_STACK *st, const void *data, int *pnum) +{ + return internal_find(st, data, OSSL_BSEARCH_FIRST_VALUE_ON_MATCH, pnum); } int OPENSSL_sk_push(OPENSSL_STACK *st, const void *data) @@ -391,8 +449,15 @@ void *OPENSSL_sk_value(const OPENSSL_STACK *st, int i) void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data) { - if (st == NULL || i < 0 || i >= st->num) + if (st == NULL) { + ERR_raise(ERR_LIB_CRYPTO, ERR_R_PASSED_NULL_PARAMETER); return NULL; + } + if (i < 0 || i >= st->num) { + ERR_raise_data(ERR_LIB_CRYPTO, ERR_R_PASSED_INVALID_ARGUMENT, + "i=%d", i); + return NULL; + } st->data[i] = data; st->sorted = 0; return (void *)st->data[i]; |
