stack_test.c 9.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /*
  2. * Copyright 2017-2021 The OpenSSL Project Authors. All Rights Reserved.
  3. * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
  4. *
  5. * Licensed under the Apache License 2.0 (the "License"). You may not use
  6. * this file except in compliance with the License. You can obtain a copy
  7. * in the file LICENSE in the source distribution or at
  8. * https://www.openssl.org/source/license.html
  9. */
  10. #include <stdio.h>
  11. #include <string.h>
  12. #include <openssl/opensslconf.h>
  13. #include <openssl/safestack.h>
  14. #include <openssl/err.h>
  15. #include <openssl/crypto.h>
  16. #include "internal/nelem.h"
  17. #include "testutil.h"
  18. /* The macros below generate unused functions which error out one of the clang
  19. * builds. We disable this check here.
  20. */
  21. #ifdef __clang__
  22. #pragma clang diagnostic ignored "-Wunused-function"
  23. #endif
  24. typedef struct {
  25. int n;
  26. char c;
  27. } SS;
  28. typedef union {
  29. int n;
  30. char c;
  31. } SU;
  32. DEFINE_SPECIAL_STACK_OF(sint, int)
  33. DEFINE_SPECIAL_STACK_OF_CONST(uchar, unsigned char)
  34. DEFINE_STACK_OF(SS)
  35. DEFINE_STACK_OF_CONST(SU)
  36. static int int_compare(const int *const *a, const int *const *b)
  37. {
  38. if (**a < **b)
  39. return -1;
  40. if (**a > **b)
  41. return 1;
  42. return 0;
  43. }
  44. static int test_int_stack(int reserve)
  45. {
  46. static int v[] = { 1, 2, -4, 16, 999, 1, -173, 1, 9 };
  47. static int notpresent = -1;
  48. const int n = OSSL_NELEM(v);
  49. static struct {
  50. int value;
  51. int unsorted;
  52. int sorted;
  53. int ex;
  54. } finds[] = {
  55. { 2, 1, 5, 5 },
  56. { 9, 7, 6, 6 },
  57. { -173, 5, 0, 0 },
  58. { 999, 3, 8, 8 },
  59. { 0, -1, -1, 1 }
  60. };
  61. const int n_finds = OSSL_NELEM(finds);
  62. static struct {
  63. int value;
  64. int ex;
  65. } exfinds[] = {
  66. { 3, 5 },
  67. { 1000, 8 },
  68. { 20, 8 },
  69. { -999, 0 },
  70. { -5, 0 },
  71. { 8, 5 }
  72. };
  73. const int n_exfinds = OSSL_NELEM(exfinds);
  74. STACK_OF(sint) *s = sk_sint_new_null();
  75. int i;
  76. int testresult = 0;
  77. if (!TEST_ptr(s)
  78. || (reserve > 0 && !TEST_true(sk_sint_reserve(s, 5 * reserve))))
  79. goto end;
  80. /* Check push and num */
  81. for (i = 0; i < n; i++) {
  82. if (!TEST_int_eq(sk_sint_num(s), i)) {
  83. TEST_info("int stack size %d", i);
  84. goto end;
  85. }
  86. sk_sint_push(s, v + i);
  87. }
  88. if (!TEST_int_eq(sk_sint_num(s), n))
  89. goto end;
  90. /* check the values */
  91. for (i = 0; i < n; i++)
  92. if (!TEST_ptr_eq(sk_sint_value(s, i), v + i)) {
  93. TEST_info("int value %d", i);
  94. goto end;
  95. }
  96. /* find unsorted -- the pointers are compared */
  97. for (i = 0; i < n_finds; i++) {
  98. int *val = (finds[i].unsorted == -1) ? &notpresent
  99. : v + finds[i].unsorted;
  100. if (!TEST_int_eq(sk_sint_find(s, val), finds[i].unsorted)) {
  101. TEST_info("int unsorted find %d", i);
  102. goto end;
  103. }
  104. }
  105. /* find_ex unsorted */
  106. for (i = 0; i < n_finds; i++) {
  107. int *val = (finds[i].unsorted == -1) ? &notpresent
  108. : v + finds[i].unsorted;
  109. if (!TEST_int_eq(sk_sint_find_ex(s, val), finds[i].unsorted)) {
  110. TEST_info("int unsorted find_ex %d", i);
  111. goto end;
  112. }
  113. }
  114. /* sorting */
  115. if (!TEST_false(sk_sint_is_sorted(s)))
  116. goto end;
  117. (void)sk_sint_set_cmp_func(s, &int_compare);
  118. sk_sint_sort(s);
  119. if (!TEST_true(sk_sint_is_sorted(s)))
  120. goto end;
  121. /* find sorted -- the value is matched so we don't need to locate it */
  122. for (i = 0; i < n_finds; i++)
  123. if (!TEST_int_eq(sk_sint_find(s, &finds[i].value), finds[i].sorted)) {
  124. TEST_info("int sorted find %d", i);
  125. goto end;
  126. }
  127. /* find_ex sorted */
  128. for (i = 0; i < n_finds; i++)
  129. if (!TEST_int_eq(sk_sint_find_ex(s, &finds[i].value), finds[i].ex)) {
  130. TEST_info("int sorted find_ex present %d", i);
  131. goto end;
  132. }
  133. for (i = 0; i < n_exfinds; i++)
  134. if (!TEST_int_eq(sk_sint_find_ex(s, &exfinds[i].value), exfinds[i].ex)){
  135. TEST_info("int sorted find_ex absent %d", i);
  136. goto end;
  137. }
  138. /* shift */
  139. if (!TEST_ptr_eq(sk_sint_shift(s), v + 6))
  140. goto end;
  141. testresult = 1;
  142. end:
  143. sk_sint_free(s);
  144. return testresult;
  145. }
  146. static int uchar_compare(const unsigned char *const *a,
  147. const unsigned char *const *b)
  148. {
  149. return **a - (signed int)**b;
  150. }
  151. static int test_uchar_stack(int reserve)
  152. {
  153. static const unsigned char v[] = { 1, 3, 7, 5, 255, 0 };
  154. const int n = OSSL_NELEM(v);
  155. STACK_OF(uchar) *s = sk_uchar_new(&uchar_compare), *r = NULL;
  156. int i;
  157. int testresult = 0;
  158. if (!TEST_ptr(s)
  159. || (reserve > 0 && !TEST_true(sk_uchar_reserve(s, 5 * reserve))))
  160. goto end;
  161. /* unshift and num */
  162. for (i = 0; i < n; i++) {
  163. if (!TEST_int_eq(sk_uchar_num(s), i)) {
  164. TEST_info("uchar stack size %d", i);
  165. goto end;
  166. }
  167. sk_uchar_unshift(s, v + i);
  168. }
  169. if (!TEST_int_eq(sk_uchar_num(s), n))
  170. goto end;
  171. /* dup */
  172. r = sk_uchar_dup(NULL);
  173. if (sk_uchar_num(r) != 0)
  174. goto end;
  175. sk_uchar_free(r);
  176. r = sk_uchar_dup(s);
  177. if (!TEST_int_eq(sk_uchar_num(r), n))
  178. goto end;
  179. sk_uchar_sort(r);
  180. /* pop */
  181. for (i = 0; i < n; i++)
  182. if (!TEST_ptr_eq(sk_uchar_pop(s), v + i)) {
  183. TEST_info("uchar pop %d", i);
  184. goto end;
  185. }
  186. /* free -- we rely on the debug malloc to detect leakage here */
  187. sk_uchar_free(s);
  188. s = NULL;
  189. /* dup again */
  190. if (!TEST_int_eq(sk_uchar_num(r), n))
  191. goto end;
  192. /* zero */
  193. sk_uchar_zero(r);
  194. if (!TEST_int_eq(sk_uchar_num(r), 0))
  195. goto end;
  196. /* insert */
  197. sk_uchar_insert(r, v, 0);
  198. sk_uchar_insert(r, v + 2, -1);
  199. sk_uchar_insert(r, v + 1, 1);
  200. for (i = 0; i < 3; i++)
  201. if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
  202. TEST_info("uchar insert %d", i);
  203. goto end;
  204. }
  205. /* delete */
  206. if (!TEST_ptr_null(sk_uchar_delete(r, 12)))
  207. goto end;
  208. if (!TEST_ptr_eq(sk_uchar_delete(r, 1), v + 1))
  209. goto end;
  210. /* set */
  211. (void)sk_uchar_set(r, 1, v + 1);
  212. for (i = 0; i < 2; i++)
  213. if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
  214. TEST_info("uchar set %d", i);
  215. goto end;
  216. }
  217. testresult = 1;
  218. end:
  219. sk_uchar_free(r);
  220. sk_uchar_free(s);
  221. return testresult;
  222. }
  223. static SS *SS_copy(const SS *p)
  224. {
  225. SS *q = OPENSSL_malloc(sizeof(*q));
  226. if (q != NULL)
  227. memcpy(q, p, sizeof(*q));
  228. return q;
  229. }
  230. static void SS_free(SS *p) {
  231. OPENSSL_free(p);
  232. }
  233. static int test_SS_stack(void)
  234. {
  235. STACK_OF(SS) *s = sk_SS_new_null();
  236. STACK_OF(SS) *r = NULL;
  237. SS *v[10], *p;
  238. const int n = OSSL_NELEM(v);
  239. int i;
  240. int testresult = 0;
  241. /* allocate and push */
  242. for (i = 0; i < n; i++) {
  243. v[i] = OPENSSL_malloc(sizeof(*v[i]));
  244. if (!TEST_ptr(v[i]))
  245. goto end;
  246. v[i]->n = i;
  247. v[i]->c = 'A' + i;
  248. if (!TEST_int_eq(sk_SS_num(s), i)) {
  249. TEST_info("SS stack size %d", i);
  250. goto end;
  251. }
  252. sk_SS_push(s, v[i]);
  253. }
  254. if (!TEST_int_eq(sk_SS_num(s), n))
  255. goto end;
  256. /* deepcopy */
  257. r = sk_SS_deep_copy(NULL, &SS_copy, &SS_free);
  258. if (sk_SS_num(r) != 0)
  259. goto end;
  260. sk_SS_free(r);
  261. r = sk_SS_deep_copy(s, &SS_copy, &SS_free);
  262. if (!TEST_ptr(r))
  263. goto end;
  264. for (i = 0; i < n; i++) {
  265. p = sk_SS_value(r, i);
  266. if (!TEST_ptr_ne(p, v[i])) {
  267. TEST_info("SS deepcopy non-copy %d", i);
  268. goto end;
  269. }
  270. if (!TEST_int_eq(p->n, v[i]->n)) {
  271. TEST_info("test SS deepcopy int %d", i);
  272. goto end;
  273. }
  274. if (!TEST_char_eq(p->c, v[i]->c)) {
  275. TEST_info("SS deepcopy char %d", i);
  276. goto end;
  277. }
  278. }
  279. /* pop_free - we rely on the malloc debug to catch the leak */
  280. sk_SS_pop_free(r, &SS_free);
  281. r = NULL;
  282. /* delete_ptr */
  283. p = sk_SS_delete_ptr(s, v[3]);
  284. if (!TEST_ptr(p))
  285. goto end;
  286. SS_free(p);
  287. if (!TEST_int_eq(sk_SS_num(s), n - 1))
  288. goto end;
  289. for (i = 0; i < n-1; i++)
  290. if (!TEST_ptr_eq(sk_SS_value(s, i), v[i<3 ? i : 1+i])) {
  291. TEST_info("SS delete ptr item %d", i);
  292. goto end;
  293. }
  294. testresult = 1;
  295. end:
  296. sk_SS_pop_free(r, &SS_free);
  297. sk_SS_pop_free(s, &SS_free);
  298. return testresult;
  299. }
  300. static int test_SU_stack(void)
  301. {
  302. STACK_OF(SU) *s = sk_SU_new_null();
  303. SU v[10];
  304. const int n = OSSL_NELEM(v);
  305. int i;
  306. int testresult = 0;
  307. /* allocate and push */
  308. for (i = 0; i < n; i++) {
  309. if ((i & 1) == 0)
  310. v[i].n = i;
  311. else
  312. v[i].c = 'A' + i;
  313. if (!TEST_int_eq(sk_SU_num(s), i)) {
  314. TEST_info("SU stack size %d", i);
  315. goto end;
  316. }
  317. sk_SU_push(s, v + i);
  318. }
  319. if (!TEST_int_eq(sk_SU_num(s), n))
  320. goto end;
  321. /* check the pointers are correct */
  322. for (i = 0; i < n; i++)
  323. if (!TEST_ptr_eq(sk_SU_value(s, i), v + i)) {
  324. TEST_info("SU pointer check %d", i);
  325. goto end;
  326. }
  327. testresult = 1;
  328. end:
  329. sk_SU_free(s);
  330. return testresult;
  331. }
  332. int setup_tests(void)
  333. {
  334. ADD_ALL_TESTS(test_int_stack, 4);
  335. ADD_ALL_TESTS(test_uchar_stack, 4);
  336. ADD_TEST(test_SS_stack);
  337. ADD_TEST(test_SU_stack);
  338. return 1;
  339. }