Add sk_TYPE_new_reserve() function
authorPaul Yang <yang.yang@baishancloud.com>
Thu, 19 Oct 2017 17:42:39 +0000 (01:42 +0800)
committerPauli <paul.dale@oracle.com>
Wed, 25 Oct 2017 23:35:36 +0000 (09:35 +1000)
This is a combination of sk_new and sk_reserve, to make it more
convenient to allocate a new stack with reserved memory and comaprison
function (if any).

Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Andy Polyakov <appro@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4559)

crypto/stack/stack.c
doc/man3/DEFINE_STACK_OF.pod
include/openssl/safestack.h
include/openssl/stack.h
util/libcrypto.num

index 559085a7b84bb96738851da6078dc31410eaef1a..fc755e36b672ec52e97e5cc071318a85d08b7ccc 100644 (file)
@@ -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)
index f41d3ead8b4a85720ed517eec300bcfff6d6cdf1..b6665bf95a9d3b075c9b5eacaf301ea73748c94b 100644 (file)
@@ -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<idx> in B<sk>, where B<idx> starts at
 zero. If B<idx> is out of range then B<NULL> is returned.
 
 sk_TYPE_new() allocates a new empty stack using comparison function B<compar>.
-If B<compar> is B<NULL> then no comparison function is used.
+If B<compar> is B<NULL> 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<sk> structure
 such that the next B<n> 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<n> is zero, any excess space allocated in the
 B<sk> structure is freed. On error B<sk> is unchanged.
 
+sk_TYPE_new_reserve() allocates a new stack. The new stack will have additional
+memory allocated to hold B<n> elements if B<n> is positive. The next B<n> 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<n> is zero or less than zero, no
+memory is allocated. sk_TYPE_reserve() also sets the comparison function
+B<compare> to the newly created stack. If B<compare> is B<NULL> then no
+comparison function is used.
+
 sk_TYPE_set_cmp_func() sets the comparison function of B<sk> to B<compar>.
 The previous comparison function is returned or B<NULL> if there was
 no previous comparison function.
@@ -210,8 +222,8 @@ passed stack is B<NULL>.
 sk_TYPE_value() returns a pointer to a stack element or B<NULL> if the
 index is out of range.
 
-sk_TYPE_new() and sk_TYPE_new_null() return an empty stack or B<NULL> if
-an error occurs.
+sk_TYPE_new(), sk_TYPE_new_null() and sk_TYPE_new_reserve() return an empty
+stack or B<NULL> 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.
index 4241c4ff3bcd269d857a0a6cae0da80f5fe753ce..7438b193608ca30fd6f16725465a3f54fbe15583 100644 (file)
@@ -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); \
index aee763c19663277e7c5bf8ec40295109b7d8ee66..cfc075057ae4bd7cd9759bb7a67a06942ea7eaae 100644 (file)
@@ -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 *));
index 96990ed959fbb6e8ba6abae66385f036998f58a2..f4e3451fdc8fc8e6d160424184c93ede93d92ec2 100644 (file)
@@ -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: