Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

395 řádky
13 KiB

  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. #include <openssl/stack.h>
  15. #include <limits.h>
  16. #include <algorithm>
  17. #include <memory>
  18. #include <utility>
  19. #include <vector>
  20. #include <gtest/gtest.h>
  21. #include <openssl/mem.h>
  22. // Define a custom stack type for testing.
  23. using TEST_INT = int;
  24. static void TEST_INT_free(TEST_INT *x) { OPENSSL_free(x); }
  25. BSSL_NAMESPACE_BEGIN
  26. BORINGSSL_MAKE_DELETER(TEST_INT, TEST_INT_free)
  27. BSSL_NAMESPACE_END
  28. static bssl::UniquePtr<TEST_INT> TEST_INT_new(int x) {
  29. bssl::UniquePtr<TEST_INT> ret(
  30. static_cast<TEST_INT *>(OPENSSL_malloc(sizeof(TEST_INT))));
  31. if (!ret) {
  32. return nullptr;
  33. }
  34. *ret = x;
  35. return ret;
  36. }
  37. DEFINE_STACK_OF(TEST_INT)
  38. struct ShallowStackDeleter {
  39. void operator()(STACK_OF(TEST_INT) *sk) const { sk_TEST_INT_free(sk); }
  40. };
  41. using ShallowStack = std::unique_ptr<STACK_OF(TEST_INT), ShallowStackDeleter>;
  42. // kNull is treated as a nullptr expectation for purposes of ExpectStackEquals.
  43. // The tests in this file will never use it as a test value.
  44. static const int kNull = INT_MIN;
  45. static void ExpectStackEquals(const STACK_OF(TEST_INT) *sk,
  46. const std::vector<int> &vec) {
  47. EXPECT_EQ(vec.size(), sk_TEST_INT_num(sk));
  48. for (size_t i = 0; i < vec.size(); i++) {
  49. SCOPED_TRACE(i);
  50. const TEST_INT *obj = sk_TEST_INT_value(sk, i);
  51. if (vec[i] == kNull) {
  52. EXPECT_FALSE(obj);
  53. } else {
  54. EXPECT_TRUE(obj);
  55. if (obj) {
  56. EXPECT_EQ(vec[i], *obj);
  57. }
  58. }
  59. }
  60. // Reading out-of-bounds fails.
  61. EXPECT_FALSE(sk_TEST_INT_value(sk, vec.size()));
  62. EXPECT_FALSE(sk_TEST_INT_value(sk, vec.size() + 1));
  63. }
  64. TEST(StackTest, Basic) {
  65. bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
  66. ASSERT_TRUE(sk);
  67. // The stack starts out empty.
  68. ExpectStackEquals(sk.get(), {});
  69. // Removing elements from an empty stack does nothing.
  70. EXPECT_FALSE(sk_TEST_INT_pop(sk.get()));
  71. EXPECT_FALSE(sk_TEST_INT_shift(sk.get()));
  72. EXPECT_FALSE(sk_TEST_INT_delete(sk.get(), 0));
  73. // Push some elements.
  74. for (int i = 0; i < 6; i++) {
  75. auto value = TEST_INT_new(i);
  76. ASSERT_TRUE(value);
  77. ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
  78. }
  79. ExpectStackEquals(sk.get(), {0, 1, 2, 3, 4, 5});
  80. // Items may be inserted in the middle.
  81. auto value = TEST_INT_new(6);
  82. ASSERT_TRUE(value);
  83. // Hold on to the object for later.
  84. TEST_INT *raw = value.get();
  85. ASSERT_TRUE(sk_TEST_INT_insert(sk.get(), value.get(), 4));
  86. value.release(); // sk_TEST_INT_insert takes ownership on success.
  87. ExpectStackEquals(sk.get(), {0, 1, 2, 3, 6, 4, 5});
  88. // Without a comparison function, find searches by pointer.
  89. value = TEST_INT_new(6);
  90. ASSERT_TRUE(value);
  91. size_t index;
  92. EXPECT_FALSE(sk_TEST_INT_find(sk.get(), &index, value.get()));
  93. ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, raw));
  94. EXPECT_EQ(4u, index);
  95. // sk_TEST_INT_insert can also insert values at the end.
  96. value = TEST_INT_new(7);
  97. ASSERT_TRUE(value);
  98. ASSERT_TRUE(sk_TEST_INT_insert(sk.get(), value.get(), 7));
  99. value.release(); // sk_TEST_INT_insert takes ownership on success.
  100. ExpectStackEquals(sk.get(), {0, 1, 2, 3, 6, 4, 5, 7});
  101. // Out-of-bounds indices are clamped.
  102. value = TEST_INT_new(8);
  103. ASSERT_TRUE(value);
  104. ASSERT_TRUE(sk_TEST_INT_insert(sk.get(), value.get(), 999));
  105. value.release(); // sk_TEST_INT_insert takes ownership on success.
  106. ExpectStackEquals(sk.get(), {0, 1, 2, 3, 6, 4, 5, 7, 8});
  107. // Test removing elements from various places.
  108. bssl::UniquePtr<TEST_INT> removed(sk_TEST_INT_pop(sk.get()));
  109. EXPECT_EQ(8, *removed);
  110. ExpectStackEquals(sk.get(), {0, 1, 2, 3, 6, 4, 5, 7});
  111. removed.reset(sk_TEST_INT_shift(sk.get()));
  112. EXPECT_EQ(0, *removed);
  113. ExpectStackEquals(sk.get(), {1, 2, 3, 6, 4, 5, 7});
  114. removed.reset(sk_TEST_INT_delete(sk.get(), 2));
  115. EXPECT_EQ(3, *removed);
  116. ExpectStackEquals(sk.get(), {1, 2, 6, 4, 5, 7});
  117. // Objects may also be deleted by pointer.
  118. removed.reset(sk_TEST_INT_delete_ptr(sk.get(), raw));
  119. EXPECT_EQ(raw, removed.get());
  120. ExpectStackEquals(sk.get(), {1, 2, 4, 5, 7});
  121. // Deleting is a no-op is the object is not found.
  122. value = TEST_INT_new(100);
  123. ASSERT_TRUE(value);
  124. EXPECT_FALSE(sk_TEST_INT_delete_ptr(sk.get(), value.get()));
  125. // Insert nullptr to test deep copy handling of it.
  126. ASSERT_TRUE(sk_TEST_INT_insert(sk.get(), nullptr, 0));
  127. ExpectStackEquals(sk.get(), {kNull, 1, 2, 4, 5, 7});
  128. // Test both deep and shallow copies.
  129. bssl::UniquePtr<STACK_OF(TEST_INT)> copy(sk_TEST_INT_deep_copy(
  130. sk.get(),
  131. [](TEST_INT *x) -> TEST_INT * {
  132. return x == nullptr ? nullptr : TEST_INT_new(*x).release();
  133. },
  134. TEST_INT_free));
  135. ASSERT_TRUE(copy);
  136. ExpectStackEquals(copy.get(), {kNull, 1, 2, 4, 5, 7});
  137. ShallowStack shallow(sk_TEST_INT_dup(sk.get()));
  138. ASSERT_TRUE(shallow);
  139. ASSERT_EQ(sk_TEST_INT_num(sk.get()), sk_TEST_INT_num(shallow.get()));
  140. for (size_t i = 0; i < sk_TEST_INT_num(sk.get()); i++) {
  141. EXPECT_EQ(sk_TEST_INT_value(sk.get(), i),
  142. sk_TEST_INT_value(shallow.get(), i));
  143. }
  144. // Deep copies may fail. This should clean up temporaries.
  145. EXPECT_FALSE(sk_TEST_INT_deep_copy(sk.get(),
  146. [](TEST_INT *x) -> TEST_INT * {
  147. return x == nullptr || *x == 4
  148. ? nullptr
  149. : TEST_INT_new(*x).release();
  150. },
  151. TEST_INT_free));
  152. // sk_TEST_INT_zero clears a stack, but does not free the elements.
  153. ShallowStack shallow2(sk_TEST_INT_dup(sk.get()));
  154. ASSERT_TRUE(shallow2);
  155. sk_TEST_INT_zero(shallow2.get());
  156. ExpectStackEquals(shallow2.get(), {});
  157. }
  158. TEST(StackTest, BigStack) {
  159. bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new_null());
  160. ASSERT_TRUE(sk);
  161. std::vector<int> expected;
  162. static const int kCount = 100000;
  163. for (int i = 0; i < kCount; i++) {
  164. auto value = TEST_INT_new(i);
  165. ASSERT_TRUE(value);
  166. ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
  167. expected.push_back(i);
  168. }
  169. ExpectStackEquals(sk.get(), expected);
  170. }
  171. static uint64_t g_compare_count = 0;
  172. static int compare(const TEST_INT **a, const TEST_INT **b) {
  173. g_compare_count++;
  174. if (**a < **b) {
  175. return -1;
  176. }
  177. if (**a > **b) {
  178. return 1;
  179. }
  180. return 0;
  181. }
  182. static int compare_reverse(const TEST_INT **a, const TEST_INT **b) {
  183. return -compare(a, b);
  184. }
  185. TEST(StackTest, Sorted) {
  186. std::vector<int> vec_sorted = {0, 1, 2, 3, 4, 5, 6};
  187. std::vector<int> vec = vec_sorted;
  188. do {
  189. bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
  190. ASSERT_TRUE(sk);
  191. for (int v : vec) {
  192. auto value = TEST_INT_new(v);
  193. ASSERT_TRUE(value);
  194. ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
  195. }
  196. // The stack is not (known to be) sorted.
  197. EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
  198. // With a comparison function, find matches by value.
  199. auto ten = TEST_INT_new(10);
  200. ASSERT_TRUE(ten);
  201. size_t index;
  202. EXPECT_FALSE(sk_TEST_INT_find(sk.get(), &index, ten.get()));
  203. auto three = TEST_INT_new(3);
  204. ASSERT_TRUE(three);
  205. ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, three.get()));
  206. EXPECT_EQ(3, *sk_TEST_INT_value(sk.get(), index));
  207. sk_TEST_INT_sort(sk.get());
  208. EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
  209. ExpectStackEquals(sk.get(), vec_sorted);
  210. // Sorting an already-sorted list is a no-op.
  211. uint64_t old_compare_count = g_compare_count;
  212. sk_TEST_INT_sort(sk.get());
  213. EXPECT_EQ(old_compare_count, g_compare_count);
  214. EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
  215. ExpectStackEquals(sk.get(), vec_sorted);
  216. // When sorted, find uses binary search.
  217. ASSERT_TRUE(ten);
  218. EXPECT_FALSE(sk_TEST_INT_find(sk.get(), &index, ten.get()));
  219. ASSERT_TRUE(three);
  220. ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, three.get()));
  221. EXPECT_EQ(3u, index);
  222. // Copies preserve comparison and sorted information.
  223. bssl::UniquePtr<STACK_OF(TEST_INT)> copy(sk_TEST_INT_deep_copy(
  224. sk.get(),
  225. [](TEST_INT *x) -> TEST_INT * { return TEST_INT_new(*x).release(); },
  226. TEST_INT_free));
  227. ASSERT_TRUE(copy);
  228. EXPECT_TRUE(sk_TEST_INT_is_sorted(copy.get()));
  229. ASSERT_TRUE(sk_TEST_INT_find(copy.get(), &index, three.get()));
  230. EXPECT_EQ(3u, index);
  231. ShallowStack copy2(sk_TEST_INT_dup(sk.get()));
  232. ASSERT_TRUE(copy2);
  233. EXPECT_TRUE(sk_TEST_INT_is_sorted(copy2.get()));
  234. ASSERT_TRUE(sk_TEST_INT_find(copy2.get(), &index, three.get()));
  235. EXPECT_EQ(3u, index);
  236. // Removing elements does not affect sortedness.
  237. TEST_INT_free(sk_TEST_INT_delete(sk.get(), 0));
  238. EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
  239. // Changing the comparison function invalidates sortedness.
  240. sk_TEST_INT_set_cmp_func(sk.get(), compare_reverse);
  241. EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
  242. ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, three.get()));
  243. EXPECT_EQ(2u, index);
  244. sk_TEST_INT_sort(sk.get());
  245. ExpectStackEquals(sk.get(), {6, 5, 4, 3, 2, 1});
  246. ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, three.get()));
  247. EXPECT_EQ(3u, index);
  248. // Inserting a new element invalidates sortedness.
  249. auto tmp = TEST_INT_new(10);
  250. ASSERT_TRUE(tmp);
  251. ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(tmp)));
  252. EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
  253. ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, ten.get()));
  254. EXPECT_EQ(6u, index);
  255. } while (std::next_permutation(vec.begin(), vec.end()));
  256. }
  257. // sk_*_find should return the first matching element in all cases.
  258. TEST(StackTest, FindFirst) {
  259. bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
  260. auto value = TEST_INT_new(1);
  261. ASSERT_TRUE(value);
  262. ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
  263. for (int i = 0; i < 10; i++) {
  264. value = TEST_INT_new(2);
  265. ASSERT_TRUE(value);
  266. ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
  267. }
  268. const TEST_INT *two = sk_TEST_INT_value(sk.get(), 1);
  269. // Pointer-based equality.
  270. size_t index;
  271. ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, two));
  272. EXPECT_EQ(1u, index);
  273. // Comparator-based equality, unsorted.
  274. sk_TEST_INT_set_cmp_func(sk.get(), compare);
  275. EXPECT_FALSE(sk_TEST_INT_is_sorted(sk.get()));
  276. ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, two));
  277. EXPECT_EQ(1u, index);
  278. // Comparator-based equality, sorted.
  279. sk_TEST_INT_sort(sk.get());
  280. EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
  281. ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, two));
  282. EXPECT_EQ(1u, index);
  283. // Comparator-based equality, sorted and at the front.
  284. sk_TEST_INT_set_cmp_func(sk.get(), compare_reverse);
  285. sk_TEST_INT_sort(sk.get());
  286. EXPECT_TRUE(sk_TEST_INT_is_sorted(sk.get()));
  287. ASSERT_TRUE(sk_TEST_INT_find(sk.get(), &index, two));
  288. EXPECT_EQ(0u, index);
  289. }
  290. // Exhaustively test the binary search.
  291. TEST(StackTest, BinarySearch) {
  292. static const size_t kCount = 100;
  293. for (size_t i = 0; i < kCount; i++) {
  294. SCOPED_TRACE(i);
  295. for (size_t j = i; j <= kCount; j++) {
  296. SCOPED_TRACE(j);
  297. // Make a stack where [0, i) are below, [i, j) match, and [j, kCount) are
  298. // above.
  299. bssl::UniquePtr<STACK_OF(TEST_INT)> sk(sk_TEST_INT_new(compare));
  300. ASSERT_TRUE(sk);
  301. for (size_t k = 0; k < i; k++) {
  302. auto value = TEST_INT_new(-1);
  303. ASSERT_TRUE(value);
  304. ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
  305. }
  306. for (size_t k = i; k < j; k++) {
  307. auto value = TEST_INT_new(0);
  308. ASSERT_TRUE(value);
  309. ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
  310. }
  311. for (size_t k = j; k < kCount; k++) {
  312. auto value = TEST_INT_new(1);
  313. ASSERT_TRUE(value);
  314. ASSERT_TRUE(bssl::PushToStack(sk.get(), std::move(value)));
  315. }
  316. sk_TEST_INT_sort(sk.get());
  317. auto key = TEST_INT_new(0);
  318. ASSERT_TRUE(key);
  319. size_t idx;
  320. int found = sk_TEST_INT_find(sk.get(), &idx, key.get());
  321. if (i == j) {
  322. EXPECT_FALSE(found);
  323. } else {
  324. ASSERT_TRUE(found);
  325. EXPECT_EQ(i, idx);
  326. }
  327. }
  328. }
  329. }