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