stack_test.c 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380
  1. /*
  2. * Copyright 2017-2020 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(s);
  173. if (!TEST_int_eq(sk_uchar_num(r), n))
  174. goto end;
  175. sk_uchar_sort(r);
  176. /* pop */
  177. for (i = 0; i < n; i++)
  178. if (!TEST_ptr_eq(sk_uchar_pop(s), v + i)) {
  179. TEST_info("uchar pop %d", i);
  180. goto end;
  181. }
  182. /* free -- we rely on the debug malloc to detect leakage here */
  183. sk_uchar_free(s);
  184. s = NULL;
  185. /* dup again */
  186. if (!TEST_int_eq(sk_uchar_num(r), n))
  187. goto end;
  188. /* zero */
  189. sk_uchar_zero(r);
  190. if (!TEST_int_eq(sk_uchar_num(r), 0))
  191. goto end;
  192. /* insert */
  193. sk_uchar_insert(r, v, 0);
  194. sk_uchar_insert(r, v + 2, -1);
  195. sk_uchar_insert(r, v + 1, 1);
  196. for (i = 0; i < 3; i++)
  197. if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
  198. TEST_info("uchar insert %d", i);
  199. goto end;
  200. }
  201. /* delete */
  202. if (!TEST_ptr_null(sk_uchar_delete(r, 12)))
  203. goto end;
  204. if (!TEST_ptr_eq(sk_uchar_delete(r, 1), v + 1))
  205. goto end;
  206. /* set */
  207. (void)sk_uchar_set(r, 1, v + 1);
  208. for (i = 0; i < 2; i++)
  209. if (!TEST_ptr_eq(sk_uchar_value(r, i), v + i)) {
  210. TEST_info("uchar set %d", i);
  211. goto end;
  212. }
  213. testresult = 1;
  214. end:
  215. sk_uchar_free(r);
  216. sk_uchar_free(s);
  217. return testresult;
  218. }
  219. static SS *SS_copy(const SS *p)
  220. {
  221. SS *q = OPENSSL_malloc(sizeof(*q));
  222. if (q != NULL)
  223. memcpy(q, p, sizeof(*q));
  224. return q;
  225. }
  226. static void SS_free(SS *p) {
  227. OPENSSL_free(p);
  228. }
  229. static int test_SS_stack(void)
  230. {
  231. STACK_OF(SS) *s = sk_SS_new_null();
  232. STACK_OF(SS) *r = NULL;
  233. SS *v[10], *p;
  234. const int n = OSSL_NELEM(v);
  235. int i;
  236. int testresult = 0;
  237. /* allocate and push */
  238. for (i = 0; i < n; i++) {
  239. v[i] = OPENSSL_malloc(sizeof(*v[i]));
  240. if (!TEST_ptr(v[i]))
  241. goto end;
  242. v[i]->n = i;
  243. v[i]->c = 'A' + i;
  244. if (!TEST_int_eq(sk_SS_num(s), i)) {
  245. TEST_info("SS stack size %d", i);
  246. goto end;
  247. }
  248. sk_SS_push(s, v[i]);
  249. }
  250. if (!TEST_int_eq(sk_SS_num(s), n))
  251. goto end;
  252. /* deepcopy */
  253. r = sk_SS_deep_copy(s, &SS_copy, &SS_free);
  254. if (!TEST_ptr(r))
  255. goto end;
  256. for (i = 0; i < n; i++) {
  257. p = sk_SS_value(r, i);
  258. if (!TEST_ptr_ne(p, v[i])) {
  259. TEST_info("SS deepcopy non-copy %d", i);
  260. goto end;
  261. }
  262. if (!TEST_int_eq(p->n, v[i]->n)) {
  263. TEST_info("test SS deepcopy int %d", i);
  264. goto end;
  265. }
  266. if (!TEST_char_eq(p->c, v[i]->c)) {
  267. TEST_info("SS deepcopy char %d", i);
  268. goto end;
  269. }
  270. }
  271. /* pop_free - we rely on the malloc debug to catch the leak */
  272. sk_SS_pop_free(r, &SS_free);
  273. r = NULL;
  274. /* delete_ptr */
  275. p = sk_SS_delete_ptr(s, v[3]);
  276. if (!TEST_ptr(p))
  277. goto end;
  278. SS_free(p);
  279. if (!TEST_int_eq(sk_SS_num(s), n - 1))
  280. goto end;
  281. for (i = 0; i < n-1; i++)
  282. if (!TEST_ptr_eq(sk_SS_value(s, i), v[i<3 ? i : 1+i])) {
  283. TEST_info("SS delete ptr item %d", i);
  284. goto end;
  285. }
  286. testresult = 1;
  287. end:
  288. sk_SS_pop_free(r, &SS_free);
  289. sk_SS_pop_free(s, &SS_free);
  290. return testresult;
  291. }
  292. static int test_SU_stack(void)
  293. {
  294. STACK_OF(SU) *s = sk_SU_new_null();
  295. SU v[10];
  296. const int n = OSSL_NELEM(v);
  297. int i;
  298. int testresult = 0;
  299. /* allocate and push */
  300. for (i = 0; i < n; i++) {
  301. if ((i & 1) == 0)
  302. v[i].n = i;
  303. else
  304. v[i].c = 'A' + i;
  305. if (!TEST_int_eq(sk_SU_num(s), i)) {
  306. TEST_info("SU stack size %d", i);
  307. goto end;
  308. }
  309. sk_SU_push(s, v + i);
  310. }
  311. if (!TEST_int_eq(sk_SU_num(s), n))
  312. goto end;
  313. /* check the pointers are correct */
  314. for (i = 0; i < n; i++)
  315. if (!TEST_ptr_eq(sk_SU_value(s, i), v + i)) {
  316. TEST_info("SU pointer check %d", i);
  317. goto end;
  318. }
  319. testresult = 1;
  320. end:
  321. sk_SU_free(s);
  322. return testresult;
  323. }
  324. int setup_tests(void)
  325. {
  326. ADD_ALL_TESTS(test_int_stack, 4);
  327. ADD_ALL_TESTS(test_uchar_stack, 4);
  328. ADD_TEST(test_SS_stack);
  329. ADD_TEST(test_SU_stack);
  330. return 1;
  331. }