1 /* Copyright (c) 2018, Google Inc.
2 *
3 * Permission to use, copy, modify, and/or distribute this software for any
4 * purpose with or without fee is hereby granted, provided that the above
5 * copyright notice and this permission notice appear in all copies.
6 *
7 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
8 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
9 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
10 * SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
11 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
12 * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
13 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */
14
15 #include <openssl/stack.h>
16
17 #include <limits.h>
18
19 #include <algorithm>
20 #include <memory>
21 #include <utility>
22 #include <vector>
23
24 #include <gtest/gtest.h>
25
26 #include <openssl/mem.h>
27 #include <openssl/rand.h>
28
29
30 // Define a custom stack type for testing.
31 using TEST_INT = int;
32
TEST_INT_free(TEST_INT * x)33 static void TEST_INT_free(TEST_INT *x) { OPENSSL_free(x); }
34
35 BSSL_NAMESPACE_BEGIN
BORINGSSL_MAKE_DELETER(TEST_INT,TEST_INT_free)36 BORINGSSL_MAKE_DELETER(TEST_INT, TEST_INT_free)
37 BSSL_NAMESPACE_END
38
39 static bssl::UniquePtr<TEST_INT> TEST_INT_new(int x) {
40 bssl::UniquePtr<TEST_INT> ret(
41 static_cast<TEST_INT *>(OPENSSL_malloc(sizeof(TEST_INT))));
42 if (!ret) {
43 return nullptr;
44 }
45 *ret = x;
46 return ret;
47 }
48
49 DEFINE_STACK_OF(TEST_INT)
50
51 struct ShallowStackDeleter {
operator ()ShallowStackDeleter52 void operator()(STACK_OF(TEST_INT) *sk) const { sk_TEST_INT_free(sk); }
53 };
54
55 using ShallowStack = std::unique_ptr<STACK_OF(TEST_INT), ShallowStackDeleter>;
56
57 // kNull is treated as a nullptr expectation for purposes of ExpectStackEquals.
58 // The tests in this file will never use it as a test value.
59 static const int kNull = INT_MIN;
60
ExpectStackEquals(const STACK_OF (TEST_INT)* sk,const std::vector<int> & vec)61 static void ExpectStackEquals(const STACK_OF(TEST_INT) *sk,
62 const std::vector<int> &vec) {
63 EXPECT_EQ(vec.size(), sk_TEST_INT_num(sk));
64 for (size_t i = 0; i < vec.size(); i++) {
65 SCOPED_TRACE(i);
66 const TEST_INT *obj = sk_TEST_INT_value(sk, i);
67 if (vec[i] == kNull) {
68 EXPECT_FALSE(obj);
69 } else {
70 EXPECT_TRUE(obj);
71 if (obj) {
72 EXPECT_EQ(vec[i], *obj);
73 }
74 }
75 }
76
77 // Reading out-of-bounds fails.
78 EXPECT_FALSE(sk_TEST_INT_value(sk, vec.size()));
79 EXPECT_FALSE(sk_TEST_INT_value(sk, vec.size() + 1));
80 }
81
TEST(StackTest,Basic)82 TEST(StackTest, Basic) {
83 bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
84 ASSERT_TRUE(sk);
85
86 // The stack starts out empty.
87 ExpectStackEquals(sk.get(), {});
88
89 // Removing elements from an empty stack does nothing.
90 EXPECT_FALSE(sk_TEST_INT_pop(sk.get()));
91 EXPECT_FALSE(sk_TEST_INT_shift(sk.get()));
92 EXPECT_FALSE(sk_TEST_INT_delete(sk.get(), 0));
93
94 // Push some elements.
95 for (int i = 0; i < 6; i++) {
96 auto value = TEST_INT_new(i);
97 ASSERT_TRUE(value);
98 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
99 }
100
101 ExpectStackEquals(sk.get(), {0, 1, 2, 3, 4, 5});
102
103 // Items may be inserted in the middle.
104 auto value = TEST_INT_new(6);
105 ASSERT_TRUE(value);
106 // Hold on to the object for later.
107 TEST_INT *raw = value.get();
108 ASSERT_TRUE(sk_TEST_INT_insert(sk.get(), value.get(), 4));
109 value.release(); // sk_TEST_INT_insert takes ownership on success.
110
111 ExpectStackEquals(sk.get(), {0, 1, 2, 3, 6, 4, 5});
112
113 // Without a comparison function, find searches by pointer.
114 value = TEST_INT_new(6);
115 ASSERT_TRUE(value);
116 size_t index;
117 EXPECT_FALSE(sk_TEST_INT_find(sk.get(), &index, value.get()));
118 ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, raw));
119 EXPECT_EQ(4u, index);
120
121 // sk_TEST_INT_insert can also insert values at the end.
122 value = TEST_INT_new(7);
123 ASSERT_TRUE(value);
124 ASSERT_TRUE(sk_TEST_INT_insert(sk.get(), value.get(), 7));
125 value.release(); // sk_TEST_INT_insert takes ownership on success.
126
127 ExpectStackEquals(sk.get(), {0, 1, 2, 3, 6, 4, 5, 7});
128
129 // Out-of-bounds indices are clamped.
130 value = TEST_INT_new(8);
131 ASSERT_TRUE(value);
132 ASSERT_TRUE(sk_TEST_INT_insert(sk.get(), value.get(), 999));
133 value.release(); // sk_TEST_INT_insert takes ownership on success.
134
135 ExpectStackEquals(sk.get(), {0, 1, 2, 3, 6, 4, 5, 7, 8});
136
137 // Test removing elements from various places.
138 bssl::UniquePtr<TEST_INT> removed(sk_TEST_INT_pop(sk.get()));
139 EXPECT_EQ(8, *removed);
140 ExpectStackEquals(sk.get(), {0, 1, 2, 3, 6, 4, 5, 7});
141
142 removed.reset(sk_TEST_INT_shift(sk.get()));
143 EXPECT_EQ(0, *removed);
144 ExpectStackEquals(sk.get(), {1, 2, 3, 6, 4, 5, 7});
145
146 removed.reset(sk_TEST_INT_delete(sk.get(), 2));
147 EXPECT_EQ(3, *removed);
148 ExpectStackEquals(sk.get(), {1, 2, 6, 4, 5, 7});
149
150 // Objects may also be deleted by pointer.
151 removed.reset(sk_TEST_INT_delete_ptr(sk.get(), raw));
152 EXPECT_EQ(raw, removed.get());
153 ExpectStackEquals(sk.get(), {1, 2, 4, 5, 7});
154
155 // Deleting is a no-op is the object is not found.
156 value = TEST_INT_new(100);
157 ASSERT_TRUE(value);
158 EXPECT_FALSE(sk_TEST_INT_delete_ptr(sk.get(), value.get()));
159
160 // Insert nullptr to test deep copy handling of it.
161 ASSERT_TRUE(sk_TEST_INT_insert(sk.get(), nullptr, 0));
162 ExpectStackEquals(sk.get(), {kNull, 1, 2, 4, 5, 7});
163
164 // Test both deep and shallow copies.
165 bssl::UniquePtr<STACK_OF(TEST_INT)> copy(sk_TEST_INT_deep_copy(
166 sk.get(),
167 [](const TEST_INT *x) -> TEST_INT * {
168 return x == nullptr ? nullptr : TEST_INT_new(*x).release();
169 },
170 TEST_INT_free));
171 ASSERT_TRUE(copy);
172 ExpectStackEquals(copy.get(), {kNull, 1, 2, 4, 5, 7});
173
174 ShallowStack shallow(sk_TEST_INT_dup(sk.get()));
175 ASSERT_TRUE(shallow);
176 ASSERT_EQ(sk_TEST_INT_num(sk.get()), sk_TEST_INT_num(shallow.get()));
177 for (size_t i = 0; i < sk_TEST_INT_num(sk.get()); i++) {
178 EXPECT_EQ(sk_TEST_INT_value(sk.get(), i),
179 sk_TEST_INT_value(shallow.get(), i));
180 }
181
182 // Deep copies may fail. This should clean up temporaries.
183 EXPECT_FALSE(sk_TEST_INT_deep_copy(
184 sk.get(),
185 [](const TEST_INT *x) -> TEST_INT * {
186 return x == nullptr || *x == 4 ? nullptr : TEST_INT_new(*x).release();
187 },
188 TEST_INT_free));
189
190 // sk_TEST_INT_zero clears a stack, but does not free the elements.
191 ShallowStack shallow2(sk_TEST_INT_dup(sk.get()));
192 ASSERT_TRUE(shallow2);
193 sk_TEST_INT_zero(shallow2.get());
194 ExpectStackEquals(shallow2.get(), {});
195 }
196
TEST(StackTest,BigStack)197 TEST(StackTest, BigStack) {
198 bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
199 ASSERT_TRUE(sk);
200
201 std::vector<int> expected;
202 static const int kCount = 100000;
203 for (int i = 0; i < kCount; i++) {
204 auto value = TEST_INT_new(i);
205 ASSERT_TRUE(value);
206 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
207 expected.push_back(i);
208 }
209 ExpectStackEquals(sk.get(), expected);
210 }
211
212 static uint64_t g_compare_count = 0;
213
compare(const TEST_INT * const * a,const TEST_INT * const * b)214 static int compare(const TEST_INT *const *a, const TEST_INT *const *b) {
215 g_compare_count++;
216 if (**a < **b) {
217 return -1;
218 }
219 if (**a > **b) {
220 return 1;
221 }
222 return 0;
223 }
224
compare_reverse(const TEST_INT * const * a,const TEST_INT * const * b)225 static int compare_reverse(const TEST_INT *const *a, const TEST_INT *const *b) {
226 return -compare(a, b);
227 }
228
TEST(StackTest,Sorted)229 TEST(StackTest, Sorted) {
230 std::vector<int> vec_sorted = {0, 1, 2, 3, 4, 5, 6};
231 std::vector<int> vec = vec_sorted;
232 do {
233 bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
234 ASSERT_TRUE(sk);
235 for (int v : vec) {
236 auto value = TEST_INT_new(v);
237 ASSERT_TRUE(value);
238 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
239 }
240
241 // The stack is not (known to be) sorted.
242 EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
243
244 // With a comparison function, find matches by value.
245 auto ten = TEST_INT_new(10);
246 ASSERT_TRUE(ten);
247 size_t index;
248 EXPECT_FALSE(sk_TEST_INT_find(sk.get(), &index, ten.get()));
249
250 auto three = TEST_INT_new(3);
251 ASSERT_TRUE(three);
252 ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, three.get()));
253 EXPECT_EQ(3, *sk_TEST_INT_value(sk.get(), index));
254
255 sk_TEST_INT_sort(sk.get());
256 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
257 ExpectStackEquals(sk.get(), vec_sorted);
258
259 // Sorting an already-sorted list is a no-op.
260 uint64_t old_compare_count = g_compare_count;
261 sk_TEST_INT_sort(sk.get());
262 EXPECT_EQ(old_compare_count, g_compare_count);
263 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
264 ExpectStackEquals(sk.get(), vec_sorted);
265
266 // When sorted, find uses binary search.
267 ASSERT_TRUE(ten);
268 EXPECT_FALSE(sk_TEST_INT_find(sk.get(), &index, ten.get()));
269
270 ASSERT_TRUE(three);
271 ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, three.get()));
272 EXPECT_EQ(3u, index);
273
274 // Copies preserve comparison and sorted information.
275 bssl::UniquePtr<STACK_OF(TEST_INT)> copy(sk_TEST_INT_deep_copy(
276 sk.get(),
277 [](const TEST_INT *x) -> TEST_INT * {
278 return TEST_INT_new(*x).release();
279 },
280 TEST_INT_free));
281 ASSERT_TRUE(copy);
282 EXPECT_TRUE(sk_TEST_INT_is_sorted(copy.get()));
283 ASSERT_TRUE(sk_TEST_INT_find(copy.get(), &index, three.get()));
284 EXPECT_EQ(3u, index);
285
286 ShallowStack copy2(sk_TEST_INT_dup(sk.get()));
287 ASSERT_TRUE(copy2);
288 EXPECT_TRUE(sk_TEST_INT_is_sorted(copy2.get()));
289 ASSERT_TRUE(sk_TEST_INT_find(copy2.get(), &index, three.get()));
290 EXPECT_EQ(3u, index);
291
292 // Removing elements does not affect sortedness.
293 TEST_INT_free(sk_TEST_INT_delete(sk.get(), 0));
294 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
295 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
296
297 // Changing the comparison function invalidates sortedness.
298 sk_TEST_INT_set_cmp_func(sk.get(), compare_reverse);
299 EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
300 ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, three.get()));
301 EXPECT_EQ(2u, index);
302
303 sk_TEST_INT_sort(sk.get());
304 ExpectStackEquals(sk.get(), {6, 5, 4, 3, 2, 1});
305 ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, three.get()));
306 EXPECT_EQ(3u, index);
307
308 // Inserting a new element invalidates sortedness.
309 auto tmp = TEST_INT_new(10);
310 ASSERT_TRUE(tmp);
311 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(tmp)));
312 EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
313 ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, ten.get()));
314 EXPECT_EQ(6u, index);
315 } while (std::next_permutation(vec.begin(), vec.end()));
316 }
317
318 // sk_*_find should return the first matching element in all cases.
TEST(StackTest,FindFirst)319 TEST(StackTest, FindFirst) {
320 bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
321 ASSERT_TRUE(sk);
322 auto value = TEST_INT_new(1);
323 ASSERT_TRUE(value);
324 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
325 for (int i = 0; i < 10; i++) {
326 value = TEST_INT_new(2);
327 ASSERT_TRUE(value);
328 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
329 }
330
331 const TEST_INT *two = sk_TEST_INT_value(sk.get(), 1);
332 // Pointer-based equality.
333 size_t index;
334 ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, two));
335 EXPECT_EQ(1u, index);
336
337 // Comparator-based equality, unsorted.
338 sk_TEST_INT_set_cmp_func(sk.get(), compare);
339 EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
340 ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, two));
341 EXPECT_EQ(1u, index);
342
343 // Comparator-based equality, sorted.
344 sk_TEST_INT_sort(sk.get());
345 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
346 ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, two));
347 EXPECT_EQ(1u, index);
348
349 // Comparator-based equality, sorted and at the front.
350 sk_TEST_INT_set_cmp_func(sk.get(), compare_reverse);
351 sk_TEST_INT_sort(sk.get());
352 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
353 ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, two));
354 EXPECT_EQ(0u, index);
355 }
356
357 // Exhaustively test the binary search.
TEST(StackTest,BinarySearch)358 TEST(StackTest, BinarySearch) {
359 static const size_t kCount = 100;
360 for (size_t i = 0; i < kCount; i++) {
361 SCOPED_TRACE(i);
362 for (size_t j = i; j <= kCount; j++) {
363 SCOPED_TRACE(j);
364 // Make a stack where [0, i) are below, [i, j) match, and [j, kCount) are
365 // above.
366 bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
367 ASSERT_TRUE(sk);
368 for (size_t k = 0; k < i; k++) {
369 auto value = TEST_INT_new(-1);
370 ASSERT_TRUE(value);
371 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
372 }
373 for (size_t k = i; k < j; k++) {
374 auto value = TEST_INT_new(0);
375 ASSERT_TRUE(value);
376 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
377 }
378 for (size_t k = j; k < kCount; k++) {
379 auto value = TEST_INT_new(1);
380 ASSERT_TRUE(value);
381 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
382 }
383 sk_TEST_INT_sort(sk.get());
384
385 auto key = TEST_INT_new(0);
386 ASSERT_TRUE(key);
387
388 size_t idx;
389 int found = sk_TEST_INT_find(sk.get(), &idx, key.get());
390 if (i == j) {
391 EXPECT_FALSE(found);
392 } else {
393 ASSERT_TRUE(found);
394 EXPECT_EQ(i, idx);
395 }
396 }
397 }
398 }
399
TEST(StackTest,DeleteIf)400 TEST(StackTest, DeleteIf) {
401 bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
402 ASSERT_TRUE(sk);
403 for (int v : {1, 9, 2, 8, 3, 7, 4, 6, 5}) {
404 auto obj = TEST_INT_new(v);
405 ASSERT_TRUE(obj);
406 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(obj)));
407 }
408
409 auto keep_only_multiples = [](TEST_INT *x, void *data) {
410 auto d = static_cast<const int *>(data);
411 if (*x % *d == 0) {
412 return 0;
413 }
414 TEST_INT_free(x);
415 return 1;
416 };
417
418 int d = 2;
419 sk_TEST_INT_delete_if(sk.get(), keep_only_multiples, &d);
420 ExpectStackEquals(sk.get(), {2, 8, 4, 6});
421
422 EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
423 sk_TEST_INT_sort(sk.get());
424 ExpectStackEquals(sk.get(), {2, 4, 6, 8});
425 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
426
427 // Keep only multiples of four.
428 d = 4;
429 sk_TEST_INT_delete_if(sk.get(), keep_only_multiples, &d);
430 ExpectStackEquals(sk.get(), {4, 8});
431
432 // Removing elements preserves the sorted bit.
433 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
434
435 // Delete everything.
436 d = 16;
437 sk_TEST_INT_delete_if(sk.get(), keep_only_multiples, &d);
438 ExpectStackEquals(sk.get(), {});
439 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
440 }
441
TEST(StackTest,IsSorted)442 TEST(StackTest, IsSorted) {
443 bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
444 ASSERT_TRUE(sk);
445 EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
446
447 // Empty lists are always known to be sorted.
448 sk_TEST_INT_set_cmp_func(sk.get(), compare);
449 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
450
451 // As are one-element lists.
452 auto value = TEST_INT_new(2);
453 ASSERT_TRUE(value);
454 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
455 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
456
457 // Two-element lists require an explicit sort.
458 value = TEST_INT_new(1);
459 ASSERT_TRUE(value);
460 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
461 EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
462
463 // The list is now sorted.
464 sk_TEST_INT_sort(sk.get());
465 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
466
467 // After changing the comparison function, it no longer is sorted.
468 sk_TEST_INT_set_cmp_func(sk.get(), compare_reverse);
469 EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
470
471 sk_TEST_INT_sort(sk.get());
472 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
473
474 // But, starting from one element, switching the comparison function preserves
475 // the sorted bit.
476 TEST_INT_free(sk_TEST_INT_pop(sk.get()));
477 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
478 sk_TEST_INT_set_cmp_func(sk.get(), compare);
479 EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
480
481 // Without a comparison function, the list cannot be sorted.
482 sk_TEST_INT_set_cmp_func(sk.get(), nullptr);
483 EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
484 }
485
TEST(StackTest,Sort)486 TEST(StackTest, Sort) {
487 constexpr size_t kMaxLength = 100;
488 constexpr int kIterations = 500;
489 for (size_t len = 0; len < kMaxLength; len++) {
490 SCOPED_TRACE(len);
491 for (int iter = 0; iter < kIterations; iter++) {
492 // Make a random input list.
493 std::vector<int> vec(len);
494 RAND_bytes(reinterpret_cast<uint8_t *>(vec.data()),
495 sizeof(int) * vec.size());
496 SCOPED_TRACE(testing::PrintToString(vec));
497
498 // Convert it to a |STACK_OF(TEST_INT)|.
499 bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
500 ASSERT_TRUE(sk);
501 for (int v : vec) {
502 auto value = TEST_INT_new(v);
503 ASSERT_TRUE(value);
504 ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
505 }
506
507 // Sort it with our sort implementation.
508 sk_TEST_INT_sort(sk.get());
509 std::vector<int> result;
510 for (const TEST_INT *v : sk.get()) {
511 result.push_back(*v);
512 }
513
514 // The result must match the STL's version.
515 std::sort(vec.begin(), vec.end());
516 EXPECT_EQ(vec, result);
517 }
518 }
519 }
520
TEST(StackTest,NullIsEmpty)521 TEST(StackTest, NullIsEmpty) {
522 EXPECT_EQ(0u, sk_TEST_INT_num(nullptr));
523
524 EXPECT_EQ(nullptr, sk_TEST_INT_value(nullptr, 0));
525 EXPECT_EQ(nullptr, sk_TEST_INT_value(nullptr, 1));
526
527 bssl::UniquePtr<TEST_INT> value = TEST_INT_new(6);
528 ASSERT_TRUE(value);
529 size_t index;
530 EXPECT_FALSE(sk_TEST_INT_find(nullptr, &index, value.get()));
531 }
532