From a013cd62f07c26c1ef99a2452b26a3ff27168822 Mon Sep 17 00:00:00 2001 From: David Benjamin Date: Fri, 22 Mar 2024 13:16:03 +1000 Subject: [PATCH] Document that null STACK_OF(T) can be used with several functions Lots of code relies on this, so we ought to document it. A null STACK_OF(T) is treated as an immutable empty list. Change-Id: I10d0ba8f7b33c7f3febaf92c2cd3da25a0eb0f80 Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/67407 Reviewed-by: Theo Buehler Auto-Submit: David Benjamin Commit-Queue: Bob Beck Reviewed-by: Bob Beck (cherry picked from commit 821fe3380cce646fa3557b882d91fba318981b9b) --- crypto/stack/stack_test.cc | 11 +++++++++++ include/openssl/stack.h | 8 ++++++-- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/crypto/stack/stack_test.cc b/crypto/stack/stack_test.cc index 6f15a74ca7..aa246956d3 100644 --- a/crypto/stack/stack_test.cc +++ b/crypto/stack/stack_test.cc @@ -508,3 +508,14 @@ TEST(StackTest, IsSorted) { sk_TEST_INT_set_cmp_func(sk.get(), nullptr); EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get())); } + +TEST(StackTest, NullIsEmpty) { + EXPECT_EQ(0u, sk_TEST_INT_num(nullptr)); + + EXPECT_EQ(nullptr, sk_TEST_INT_value(nullptr, 0)); + EXPECT_EQ(nullptr, sk_TEST_INT_value(nullptr, 1)); + + bssl::UniquePtr value = TEST_INT_new(6); + ASSERT_TRUE(value); + //EXPECT_FALSE(sk_TEST_INT_find(nullptr, value.get())); +} diff --git a/include/openssl/stack.h b/include/openssl/stack.h index bb82e7eb86..7ff03fe48b 100644 --- a/include/openssl/stack.h +++ b/include/openssl/stack.h @@ -143,7 +143,8 @@ STACK_OF(SAMPLE) *sk_SAMPLE_new(sk_SAMPLE_cmp_func comp); STACK_OF(SAMPLE) *sk_SAMPLE_new_null(void); // sk_SAMPLE_num returns the number of elements in |sk|. It is safe to cast this -// value to |int|. |sk| is guaranteed to have at most |INT_MAX| elements. +// value to |int|. |sk| is guaranteed to have at most |INT_MAX| elements. If +// |sk| is NULL, it is treated as the empty list and this function returns zero. size_t sk_SAMPLE_num(const STACK_OF(SAMPLE) *sk); // sk_SAMPLE_zero resets |sk| to the empty state but does nothing to free the @@ -151,7 +152,8 @@ size_t sk_SAMPLE_num(const STACK_OF(SAMPLE) *sk); void sk_SAMPLE_zero(STACK_OF(SAMPLE) *sk); // sk_SAMPLE_value returns the |i|th pointer in |sk|, or NULL if |i| is out of -// range. +// range. If |sk| is NULL, it is treated as an empty list and the function +// returns NULL. SAMPLE *sk_SAMPLE_value(const STACK_OF(SAMPLE) *sk, size_t i); // sk_SAMPLE_set sets the |i|th pointer in |sk| to |p| and returns |p|. If |i| @@ -199,6 +201,8 @@ void sk_SAMPLE_delete_if(STACK_OF(SAMPLE) *sk, sk_SAMPLE_delete_if_func func, // If the stack is sorted (see |sk_SAMPLE_sort|), this function uses a binary // search. Otherwise it performs a linear search. If it finds a matching // element, it returns the index of that element. Otherwise, it returns -1. +// If |sk| is NULL, it is treated as the empty list and the function returns +// zero. // // Note this differs from OpenSSL in that OpenSSL's version will implicitly // sort |sk| if it has a comparison function defined.