stack_test.c 9.0 KB

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