diff --git a/crypto/stack/stack.c b/crypto/stack/stack.c index 559085a7b8..fc755e36b6 100644 --- a/crypto/stack/stack.c +++ b/crypto/stack/stack.c @@ -111,16 +111,12 @@ OPENSSL_STACK *OPENSSL_sk_deep_copy(const OPENSSL_STACK *sk, OPENSSL_STACK *OPENSSL_sk_new_null(void) { - return OPENSSL_zalloc(sizeof(OPENSSL_STACK)); + return OPENSSL_sk_new_reserve(NULL, 0); } OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc c) { - OPENSSL_STACK *ret = OPENSSL_sk_new_null(); - - if (ret != NULL) - ret->comp = c; - return ret; + return OPENSSL_sk_new_reserve(c, 0); } /* @@ -203,6 +199,26 @@ static int sk_reserve(OPENSSL_STACK *st, int n, int exact) return 1; } +OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n) +{ + OPENSSL_STACK *st = OPENSSL_zalloc(sizeof(OPENSSL_STACK)); + + if (st == NULL) + return NULL; + + st->comp = c; + + if (n <= 0) + return st; + + if (!sk_reserve(st, n, 1)) { + OPENSSL_sk_free(st); + return NULL; + } + + return st; +} + int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n) { if (st == NULL) diff --git a/doc/man3/DEFINE_STACK_OF.pod b/doc/man3/DEFINE_STACK_OF.pod index f41d3ead8b..b6665bf95a 100644 --- a/doc/man3/DEFINE_STACK_OF.pod +++ b/doc/man3/DEFINE_STACK_OF.pod @@ -9,7 +9,8 @@ sk_TYPE_reserve, sk_TYPE_free, sk_TYPE_zero, sk_TYPE_delete, sk_TYPE_delete_ptr, sk_TYPE_push, sk_TYPE_unshift, sk_TYPE_pop, sk_TYPE_shift, sk_TYPE_pop_free, sk_TYPE_insert, sk_TYPE_set, sk_TYPE_find, sk_TYPE_find_ex, sk_TYPE_sort, sk_TYPE_is_sorted, -sk_TYPE_dup, sk_TYPE_deep_copy, sk_TYPE_set_cmp_func - stack container +sk_TYPE_dup, sk_TYPE_deep_copy, sk_TYPE_set_cmp_func, sk_TYPE_new_reserve +- stack container =head1 SYNOPSIS @@ -53,6 +54,7 @@ sk_TYPE_dup, sk_TYPE_deep_copy, sk_TYPE_set_cmp_func - stack container sk_TYPE_freefunc freefunc); sk_TYPE_compfunc (*sk_TYPE_set_cmp_func(STACK_OF(TYPE) *sk, sk_TYPE_compfunc compare)); + STACK_OF(TYPE) *sk_TYPE_new_reserve(sk_TYPE_compfunc compare, int n); =head1 DESCRIPTION @@ -91,9 +93,11 @@ sk_TYPE_value() returns element B in B, where B starts at zero. If B is out of range then B is returned. sk_TYPE_new() allocates a new empty stack using comparison function B. -If B is B then no comparison function is used. +If B is B then no comparison function is used. This function is +equivalent to sk_TYPE_new_reserve(compare, 0). -sk_TYPE_new_null() allocates a new empty stack with no comparison function. +sk_TYPE_new_null() allocates a new empty stack with no comparison function. This +function is equivalent to sk_TYPE_new_reserve(NULL, 0). sk_TYPE_reserve() allocates additional memory in the B structure such that the next B calls to sk_TYPE_insert(), sk_TYPE_push() @@ -101,6 +105,14 @@ or sk_TYPE_unshift() will not fail or cause memory to be allocated or reallocated. If B is zero, any excess space allocated in the B structure is freed. On error B is unchanged. +sk_TYPE_new_reserve() allocates a new stack. The new stack will have additional +memory allocated to hold B elements if B is positive. The next B calls +to sk_TYPE_insert(), sk_TYPE_push() or sk_TYPE_unshift() will not fail or cause +memory to be allocated or reallocated. If B is zero or less than zero, no +memory is allocated. sk_TYPE_reserve() also sets the comparison function +B to the newly created stack. If B is B then no +comparison function is used. + sk_TYPE_set_cmp_func() sets the comparison function of B to B. The previous comparison function is returned or B if there was no previous comparison function. @@ -210,8 +222,8 @@ passed stack is B. sk_TYPE_value() returns a pointer to a stack element or B if the index is out of range. -sk_TYPE_new() and sk_TYPE_new_null() return an empty stack or B if -an error occurs. +sk_TYPE_new(), sk_TYPE_new_null() and sk_TYPE_new_reserve() return an empty +stack or B if an error occurs. sk_TYPE_reserve() returns B<1> on successful allocation of the required memory or B<0> on error. @@ -245,6 +257,8 @@ stack. Before OpenSSL 1.1.0, this was implemented via macros and not inline functions and was not a public API. +sk_TYPE_new_reserve() was added in OpenSSL 1.1.1. + =head1 COPYRIGHT Copyright 2000-2017 The OpenSSL Project Authors. All Rights Reserved. diff --git a/include/openssl/safestack.h b/include/openssl/safestack.h index 4241c4ff3b..7438b19360 100644 --- a/include/openssl/safestack.h +++ b/include/openssl/safestack.h @@ -40,6 +40,10 @@ extern "C" { { \ return (STACK_OF(t1) *)OPENSSL_sk_new_null(); \ } \ + static ossl_inline STACK_OF(t1) *sk_##t1##_new_reserve(sk_##t1##_compfunc compare, int n) \ + { \ + return (STACK_OF(t1) *)OPENSSL_sk_new_reserve((OPENSSL_sk_compfunc)compare, n); \ + } \ static ossl_inline int sk_##t1##_reserve(STACK_OF(t1) *sk, int n) \ { \ return OPENSSL_sk_reserve((OPENSSL_STACK *)sk, n); \ diff --git a/include/openssl/stack.h b/include/openssl/stack.h index aee763c196..cfc075057a 100644 --- a/include/openssl/stack.h +++ b/include/openssl/stack.h @@ -27,6 +27,7 @@ void *OPENSSL_sk_set(OPENSSL_STACK *st, int i, const void *data); OPENSSL_STACK *OPENSSL_sk_new(OPENSSL_sk_compfunc cmp); OPENSSL_STACK *OPENSSL_sk_new_null(void); +OPENSSL_STACK *OPENSSL_sk_new_reserve(OPENSSL_sk_compfunc c, int n); int OPENSSL_sk_reserve(OPENSSL_STACK *st, int n); void OPENSSL_sk_free(OPENSSL_STACK *); void OPENSSL_sk_pop_free(OPENSSL_STACK *st, void (*func) (void *)); diff --git a/util/libcrypto.num b/util/libcrypto.num index 96990ed959..f4e3451fdc 100644 --- a/util/libcrypto.num +++ b/util/libcrypto.num @@ -4417,3 +4417,4 @@ RAND_POOL_add 4361 1_1_1 EXIST::FUNCTION: RAND_POOL_add_begin 4362 1_1_1 EXIST::FUNCTION: RAND_POOL_add_end 4363 1_1_1 EXIST::FUNCTION: RAND_POOL_acquire_entropy 4364 1_1_1 EXIST::FUNCTION: +OPENSSL_sk_new_reserve 4365 1_1_1 EXIST::FUNCTION: