tst-alloc_buffer.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665
  1. /* Tests for struct alloc_buffer.
  2. Copyright (C) 2017-2019 Free Software Foundation, Inc.
  3. This file is part of the GNU C Library.
  4. The GNU C Library is free software; you can redistribute it and/or
  5. modify it under the terms of the GNU Lesser General Public
  6. License as published by the Free Software Foundation; either
  7. version 2.1 of the License, or (at your option) any later version.
  8. The GNU C Library is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  11. Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public
  13. License along with the GNU C Library; if not, see
  14. <http://www.gnu.org/licenses/>. */
  15. #include <arpa/inet.h>
  16. #include <alloc_buffer.h>
  17. #include <stdio.h>
  18. #include <stdlib.h>
  19. #include <string.h>
  20. #include <support/check.h>
  21. #include <support/support.h>
  22. #include <support/test-driver.h>
  23. /* Return true if PTR is sufficiently aligned for TYPE. */
  24. #define IS_ALIGNED(ptr, type) \
  25. ((((uintptr_t) ptr) & (__alloc_buffer_assert_align (__alignof (type)) - 1)) \
  26. == 0)
  27. /* Structure with non-power-of-two size. */
  28. struct twelve
  29. {
  30. uint32_t buffer[3] __attribute__ ((aligned (4)));
  31. };
  32. _Static_assert (sizeof (struct twelve) == 12, "struct twelve");
  33. _Static_assert (__alignof__ (struct twelve) == 4, "struct twelve");
  34. /* Check for success obtaining empty arrays. Does not assume the
  35. buffer is empty. */
  36. static void
  37. test_empty_array (struct alloc_buffer refbuf)
  38. {
  39. bool refbuf_failed = alloc_buffer_has_failed (&refbuf);
  40. if (test_verbose)
  41. printf ("info: %s: current=0x%llx end=0x%llx refbuf_failed=%d\n",
  42. __func__, (unsigned long long) refbuf.__alloc_buffer_current,
  43. (unsigned long long) refbuf.__alloc_buffer_end, refbuf_failed);
  44. {
  45. struct alloc_buffer buf = refbuf;
  46. TEST_VERIFY ((alloc_buffer_alloc_bytes (&buf, 0) == NULL)
  47. == refbuf_failed);
  48. TEST_VERIFY (alloc_buffer_has_failed (&buf) == refbuf_failed);
  49. }
  50. {
  51. struct alloc_buffer buf = refbuf;
  52. TEST_VERIFY ((alloc_buffer_alloc_array (&buf, char, 0) == NULL)
  53. == refbuf_failed);
  54. TEST_VERIFY (alloc_buffer_has_failed (&buf) == refbuf_failed);
  55. }
  56. /* The following tests can fail due to the need for aligning the
  57. returned pointer. */
  58. {
  59. struct alloc_buffer buf = refbuf;
  60. bool expect_failure = refbuf_failed
  61. || !IS_ALIGNED (alloc_buffer_next (&buf, void), double);
  62. double *ptr = alloc_buffer_alloc_array (&buf, double, 0);
  63. TEST_VERIFY (IS_ALIGNED (ptr, double));
  64. TEST_VERIFY ((ptr == NULL) == expect_failure);
  65. TEST_VERIFY (alloc_buffer_has_failed (&buf) == expect_failure);
  66. }
  67. {
  68. struct alloc_buffer buf = refbuf;
  69. bool expect_failure = refbuf_failed
  70. || !IS_ALIGNED (alloc_buffer_next (&buf, void), struct twelve);
  71. struct twelve *ptr = alloc_buffer_alloc_array (&buf, struct twelve, 0);
  72. TEST_VERIFY (IS_ALIGNED (ptr, struct twelve));
  73. TEST_VERIFY ((ptr == NULL) == expect_failure);
  74. TEST_VERIFY (alloc_buffer_has_failed (&buf) == expect_failure);
  75. }
  76. }
  77. /* Test allocation of impossibly large arrays. */
  78. static void
  79. test_impossible_array (struct alloc_buffer refbuf)
  80. {
  81. if (test_verbose)
  82. printf ("info: %s: current=0x%llx end=0x%llx\n",
  83. __func__, (unsigned long long) refbuf.__alloc_buffer_current,
  84. (unsigned long long) refbuf.__alloc_buffer_end);
  85. static const size_t counts[] =
  86. { SIZE_MAX, SIZE_MAX - 1, SIZE_MAX - 2, SIZE_MAX - 3, SIZE_MAX - 4,
  87. SIZE_MAX / 2, SIZE_MAX / 2 + 1, SIZE_MAX / 2 - 1, 0};
  88. for (int i = 0; counts[i] != 0; ++i)
  89. {
  90. size_t count = counts[i];
  91. if (test_verbose)
  92. printf ("info: %s: count=%zu\n", __func__, count);
  93. {
  94. struct alloc_buffer buf = refbuf;
  95. TEST_VERIFY (alloc_buffer_alloc_bytes (&buf, count) == NULL);
  96. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  97. }
  98. {
  99. struct alloc_buffer buf = refbuf;
  100. TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, count) == NULL);
  101. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  102. }
  103. {
  104. struct alloc_buffer buf = refbuf;
  105. TEST_VERIFY (alloc_buffer_alloc_array (&buf, short, count) == NULL);
  106. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  107. }
  108. {
  109. struct alloc_buffer buf = refbuf;
  110. TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, count) == NULL);
  111. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  112. }
  113. {
  114. struct alloc_buffer buf = refbuf;
  115. TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, count)
  116. == NULL);
  117. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  118. }
  119. }
  120. }
  121. /* Check for failure to obtain anything from a failed buffer. */
  122. static void
  123. test_after_failure (struct alloc_buffer refbuf)
  124. {
  125. if (test_verbose)
  126. printf ("info: %s: current=0x%llx end=0x%llx\n",
  127. __func__, (unsigned long long) refbuf.__alloc_buffer_current,
  128. (unsigned long long) refbuf.__alloc_buffer_end);
  129. TEST_VERIFY (alloc_buffer_has_failed (&refbuf));
  130. {
  131. struct alloc_buffer buf = refbuf;
  132. alloc_buffer_add_byte (&buf, 17);
  133. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  134. }
  135. {
  136. struct alloc_buffer buf = refbuf;
  137. TEST_VERIFY (alloc_buffer_alloc (&buf, char) == NULL);
  138. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  139. }
  140. {
  141. struct alloc_buffer buf = refbuf;
  142. TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL);
  143. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  144. }
  145. {
  146. struct alloc_buffer buf = refbuf;
  147. TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL);
  148. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  149. }
  150. test_impossible_array (refbuf);
  151. for (int count = 0; count <= 4; ++count)
  152. {
  153. {
  154. struct alloc_buffer buf = refbuf;
  155. TEST_VERIFY (alloc_buffer_alloc_bytes (&buf, count) == NULL);
  156. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  157. }
  158. {
  159. struct alloc_buffer buf = refbuf;
  160. TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, count) == NULL);
  161. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  162. }
  163. {
  164. struct alloc_buffer buf = refbuf;
  165. TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, count) == NULL);
  166. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  167. }
  168. {
  169. struct alloc_buffer buf = refbuf;
  170. TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, count)
  171. == NULL);
  172. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  173. }
  174. }
  175. }
  176. static void
  177. test_empty (struct alloc_buffer refbuf)
  178. {
  179. TEST_VERIFY (alloc_buffer_size (&refbuf) == 0);
  180. if (alloc_buffer_next (&refbuf, void) != NULL)
  181. TEST_VERIFY (!alloc_buffer_has_failed (&refbuf));
  182. test_empty_array (refbuf);
  183. test_impossible_array (refbuf);
  184. /* Failure to obtain non-empty objects. */
  185. {
  186. struct alloc_buffer buf = refbuf;
  187. alloc_buffer_add_byte (&buf, 17);
  188. test_after_failure (buf);
  189. }
  190. {
  191. struct alloc_buffer buf = refbuf;
  192. TEST_VERIFY (alloc_buffer_alloc (&buf, char) == NULL);
  193. test_after_failure (buf);
  194. }
  195. {
  196. struct alloc_buffer buf = refbuf;
  197. TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL);
  198. test_after_failure (buf);
  199. }
  200. {
  201. struct alloc_buffer buf = refbuf;
  202. TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL);
  203. test_after_failure (buf);
  204. }
  205. {
  206. struct alloc_buffer buf = refbuf;
  207. TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, 1) == NULL);
  208. test_after_failure (buf);
  209. }
  210. {
  211. struct alloc_buffer buf = refbuf;
  212. TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, 1) == NULL);
  213. test_after_failure (buf);
  214. }
  215. {
  216. struct alloc_buffer buf = refbuf;
  217. TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, 1) == NULL);
  218. test_after_failure (buf);
  219. }
  220. }
  221. static void
  222. test_size_1 (struct alloc_buffer refbuf)
  223. {
  224. TEST_VERIFY (!alloc_buffer_has_failed (&refbuf));
  225. TEST_VERIFY (alloc_buffer_size (&refbuf) == 1);
  226. test_empty_array (refbuf);
  227. test_impossible_array (refbuf);
  228. /* Success adding a single byte. */
  229. {
  230. struct alloc_buffer buf = refbuf;
  231. alloc_buffer_add_byte (&buf, 17);
  232. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  233. test_empty (buf);
  234. }
  235. TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\x11", 1) == 0);
  236. {
  237. struct alloc_buffer buf = refbuf;
  238. signed char *ptr = alloc_buffer_alloc (&buf, signed char);
  239. TEST_VERIFY_EXIT (ptr != NULL);
  240. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  241. *ptr = 126;
  242. test_empty (buf);
  243. }
  244. TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\176", 1) == 0);
  245. {
  246. struct alloc_buffer buf = refbuf;
  247. char *ptr = alloc_buffer_alloc_array (&buf, char, 1);
  248. TEST_VERIFY_EXIT (ptr != NULL);
  249. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  250. *ptr = (char) 253;
  251. test_empty (buf);
  252. }
  253. TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\xfd", 1) == 0);
  254. /* Failure with larger objects. */
  255. {
  256. struct alloc_buffer buf = refbuf;
  257. TEST_VERIFY (alloc_buffer_alloc (&buf, short) == NULL);
  258. test_after_failure (buf);
  259. }
  260. {
  261. struct alloc_buffer buf = refbuf;
  262. TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL);
  263. test_after_failure (buf);
  264. }
  265. {
  266. struct alloc_buffer buf = refbuf;
  267. TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL);
  268. test_after_failure (buf);
  269. }
  270. {
  271. struct alloc_buffer buf = refbuf;
  272. TEST_VERIFY (alloc_buffer_alloc_array (&buf, short, 1) == NULL);
  273. test_after_failure (buf);
  274. }
  275. {
  276. struct alloc_buffer buf = refbuf;
  277. TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, 1) == NULL);
  278. test_after_failure (buf);
  279. }
  280. {
  281. struct alloc_buffer buf = refbuf;
  282. TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, 1) == NULL);
  283. test_after_failure (buf);
  284. }
  285. }
  286. static void
  287. test_size_2 (struct alloc_buffer refbuf)
  288. {
  289. TEST_VERIFY (!alloc_buffer_has_failed (&refbuf));
  290. TEST_VERIFY (alloc_buffer_size (&refbuf) == 2);
  291. TEST_VERIFY (IS_ALIGNED (alloc_buffer_next (&refbuf, void), short));
  292. test_empty_array (refbuf);
  293. test_impossible_array (refbuf);
  294. /* Success adding two bytes. */
  295. {
  296. struct alloc_buffer buf = refbuf;
  297. alloc_buffer_add_byte (&buf, '@');
  298. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  299. test_size_1 (buf);
  300. }
  301. TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "@\xfd", 2) == 0);
  302. {
  303. struct alloc_buffer buf = refbuf;
  304. signed char *ptr = alloc_buffer_alloc (&buf, signed char);
  305. TEST_VERIFY_EXIT (ptr != NULL);
  306. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  307. *ptr = 'A';
  308. test_size_1 (buf);
  309. }
  310. TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "A\xfd", 2) == 0);
  311. {
  312. struct alloc_buffer buf = refbuf;
  313. char *ptr = alloc_buffer_alloc_array (&buf, char, 1);
  314. TEST_VERIFY_EXIT (ptr != NULL);
  315. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  316. *ptr = 'B';
  317. test_size_1 (buf);
  318. }
  319. TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "B\xfd", 2) == 0);
  320. {
  321. struct alloc_buffer buf = refbuf;
  322. unsigned short *ptr = alloc_buffer_alloc (&buf, unsigned short);
  323. TEST_VERIFY_EXIT (ptr != NULL);
  324. TEST_VERIFY (IS_ALIGNED (ptr, unsigned short));
  325. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  326. *ptr = htons (0x12f4);
  327. test_empty (buf);
  328. }
  329. TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\x12\xf4", 2) == 0);
  330. {
  331. struct alloc_buffer buf = refbuf;
  332. unsigned short *ptr = alloc_buffer_alloc_array (&buf, unsigned short, 1);
  333. TEST_VERIFY_EXIT (ptr != NULL);
  334. TEST_VERIFY (IS_ALIGNED (ptr, unsigned short));
  335. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  336. *ptr = htons (0x13f5);
  337. test_empty (buf);
  338. }
  339. TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\x13\xf5", 2) == 0);
  340. {
  341. struct alloc_buffer buf = refbuf;
  342. char *ptr = alloc_buffer_alloc_array (&buf, char, 2);
  343. TEST_VERIFY_EXIT (ptr != NULL);
  344. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  345. memcpy (ptr, "12", 2);
  346. test_empty (buf);
  347. }
  348. TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "12", 2) == 0);
  349. }
  350. static void
  351. test_misaligned (char pad)
  352. {
  353. enum { SIZE = 23 };
  354. char *backing = xmalloc (SIZE + 2);
  355. backing[0] = ~pad;
  356. backing[SIZE + 1] = pad;
  357. struct alloc_buffer refbuf = alloc_buffer_create (backing + 1, SIZE);
  358. {
  359. struct alloc_buffer buf = refbuf;
  360. short *ptr = alloc_buffer_alloc_array (&buf, short, SIZE / sizeof (short));
  361. TEST_VERIFY_EXIT (ptr != NULL);
  362. TEST_VERIFY (IS_ALIGNED (ptr, short));
  363. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  364. for (int i = 0; i < SIZE / sizeof (short); ++i)
  365. ptr[i] = htons (0xff01 + i);
  366. TEST_VERIFY (memcmp (ptr,
  367. "\xff\x01\xff\x02\xff\x03\xff\x04"
  368. "\xff\x05\xff\x06\xff\x07\xff\x08"
  369. "\xff\x09\xff\x0a\xff\x0b", 22) == 0);
  370. }
  371. {
  372. struct alloc_buffer buf = refbuf;
  373. uint32_t *ptr = alloc_buffer_alloc_array
  374. (&buf, uint32_t, SIZE / sizeof (uint32_t));
  375. TEST_VERIFY_EXIT (ptr != NULL);
  376. TEST_VERIFY (IS_ALIGNED (ptr, uint32_t));
  377. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  378. for (int i = 0; i < SIZE / sizeof (uint32_t); ++i)
  379. ptr[i] = htonl (0xf1e2d301 + i);
  380. TEST_VERIFY (memcmp (ptr,
  381. "\xf1\xe2\xd3\x01\xf1\xe2\xd3\x02"
  382. "\xf1\xe2\xd3\x03\xf1\xe2\xd3\x04"
  383. "\xf1\xe2\xd3\x05", 20) == 0);
  384. }
  385. {
  386. struct alloc_buffer buf = refbuf;
  387. struct twelve *ptr = alloc_buffer_alloc (&buf, struct twelve);
  388. TEST_VERIFY_EXIT (ptr != NULL);
  389. TEST_VERIFY (IS_ALIGNED (ptr, struct twelve));
  390. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  391. ptr->buffer[0] = htonl (0x11223344);
  392. ptr->buffer[1] = htonl (0x55667788);
  393. ptr->buffer[2] = htonl (0x99aabbcc);
  394. TEST_VERIFY (memcmp (ptr,
  395. "\x11\x22\x33\x44"
  396. "\x55\x66\x77\x88"
  397. "\x99\xaa\xbb\xcc", 12) == 0);
  398. }
  399. {
  400. static const double nums[] = { 1, 2 };
  401. struct alloc_buffer buf = refbuf;
  402. double *ptr = alloc_buffer_alloc_array (&buf, double, 2);
  403. TEST_VERIFY_EXIT (ptr != NULL);
  404. TEST_VERIFY (IS_ALIGNED (ptr, double));
  405. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  406. ptr[0] = nums[0];
  407. ptr[1] = nums[1];
  408. TEST_VERIFY (memcmp (ptr, nums, sizeof (nums)) == 0);
  409. }
  410. /* Verify that padding was not overwritten. */
  411. TEST_VERIFY (backing[0] == (char) ~pad);
  412. TEST_VERIFY (backing[SIZE + 1] == pad);
  413. free (backing);
  414. }
  415. /* Check that overflow during alignment is handled properly. */
  416. static void
  417. test_large_misaligned (void)
  418. {
  419. uintptr_t minus1 = -1;
  420. uintptr_t start = minus1 & ~0xfe;
  421. struct alloc_buffer refbuf = alloc_buffer_create ((void *) start, 16);
  422. TEST_VERIFY (!alloc_buffer_has_failed (&refbuf));
  423. struct __attribute__ ((aligned (256))) align256
  424. {
  425. int dymmy;
  426. };
  427. {
  428. struct alloc_buffer buf = refbuf;
  429. TEST_VERIFY (alloc_buffer_alloc (&buf, struct align256) == NULL);
  430. test_after_failure (buf);
  431. }
  432. for (int count = 0; count < 3; ++count)
  433. {
  434. struct alloc_buffer buf = refbuf;
  435. TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct align256, count)
  436. == NULL);
  437. test_after_failure (buf);
  438. }
  439. }
  440. /* Check behavior of large allocations. */
  441. static void
  442. test_large (void)
  443. {
  444. {
  445. /* Allocation which wraps around. */
  446. struct alloc_buffer buf = { 1, SIZE_MAX };
  447. TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, SIZE_MAX) == NULL);
  448. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  449. }
  450. {
  451. /* Successful very large allocation. */
  452. struct alloc_buffer buf = { 1, SIZE_MAX };
  453. uintptr_t val = (uintptr_t) alloc_buffer_alloc_array
  454. (&buf, char, SIZE_MAX - 1);
  455. TEST_VERIFY (val == 1);
  456. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  457. test_empty (buf);
  458. }
  459. {
  460. typedef char __attribute__ ((aligned (2))) char2;
  461. /* Overflow in array size computation. */
  462. struct alloc_buffer buf = { 1, SIZE_MAX };
  463. TEST_VERIFY (alloc_buffer_alloc_array (&buf, char2, SIZE_MAX - 1) == NULL);
  464. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  465. /* Successful allocation after alignment. */
  466. buf = (struct alloc_buffer) { 1, SIZE_MAX };
  467. uintptr_t val = (uintptr_t) alloc_buffer_alloc_array
  468. (&buf, char2, SIZE_MAX - 2);
  469. TEST_VERIFY (val == 2);
  470. test_empty (buf);
  471. /* Alignment behavior near the top of the address space. */
  472. buf = (struct alloc_buffer) { SIZE_MAX, SIZE_MAX };
  473. TEST_VERIFY (alloc_buffer_next (&buf, char2) == NULL);
  474. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  475. buf = (struct alloc_buffer) { SIZE_MAX, SIZE_MAX };
  476. TEST_VERIFY (alloc_buffer_alloc_array (&buf, char2, 0) == NULL);
  477. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  478. }
  479. {
  480. typedef short __attribute__ ((aligned (2))) short2;
  481. /* Test overflow in size computation. */
  482. struct alloc_buffer buf = { 1, SIZE_MAX };
  483. TEST_VERIFY (alloc_buffer_alloc_array (&buf, short2, SIZE_MAX / 2)
  484. == NULL);
  485. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  486. /* A slightly smaller array fits within the allocation. */
  487. buf = (struct alloc_buffer) { 2, SIZE_MAX - 1 };
  488. uintptr_t val = (uintptr_t) alloc_buffer_alloc_array
  489. (&buf, short2, SIZE_MAX / 2 - 1);
  490. TEST_VERIFY (val == 2);
  491. test_empty (buf);
  492. }
  493. }
  494. static void
  495. test_copy_bytes (void)
  496. {
  497. char backing[4];
  498. {
  499. memset (backing, '@', sizeof (backing));
  500. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  501. alloc_buffer_copy_bytes (&buf, "1", 1);
  502. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  503. TEST_VERIFY (alloc_buffer_size (&buf) == 3);
  504. TEST_VERIFY (memcmp (backing, "1@@@", 4) == 0);
  505. }
  506. {
  507. memset (backing, '@', sizeof (backing));
  508. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  509. alloc_buffer_copy_bytes (&buf, "12", 3);
  510. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  511. TEST_VERIFY (alloc_buffer_size (&buf) == 1);
  512. TEST_VERIFY (memcmp (backing, "12\0@", 4) == 0);
  513. }
  514. {
  515. memset (backing, '@', sizeof (backing));
  516. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  517. alloc_buffer_copy_bytes (&buf, "1234", 4);
  518. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  519. TEST_VERIFY (alloc_buffer_size (&buf) == 0);
  520. TEST_VERIFY (memcmp (backing, "1234", 4) == 0);
  521. }
  522. {
  523. memset (backing, '@', sizeof (backing));
  524. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  525. alloc_buffer_copy_bytes (&buf, "1234", 5);
  526. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  527. TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0);
  528. }
  529. {
  530. memset (backing, '@', sizeof (backing));
  531. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  532. alloc_buffer_copy_bytes (&buf, "1234", -1);
  533. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  534. TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0);
  535. }
  536. }
  537. static void
  538. test_copy_string (void)
  539. {
  540. char backing[4];
  541. {
  542. memset (backing, '@', sizeof (backing));
  543. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  544. const char *p = alloc_buffer_copy_string (&buf, "");
  545. TEST_VERIFY (p == backing);
  546. TEST_VERIFY (strcmp (p, "") == 0);
  547. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  548. TEST_VERIFY (alloc_buffer_size (&buf) == 3);
  549. TEST_VERIFY (memcmp (backing, "\0@@@", 4) == 0);
  550. }
  551. {
  552. memset (backing, '@', sizeof (backing));
  553. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  554. const char *p = alloc_buffer_copy_string (&buf, "1");
  555. TEST_VERIFY (p == backing);
  556. TEST_VERIFY (strcmp (p, "1") == 0);
  557. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  558. TEST_VERIFY (alloc_buffer_size (&buf) == 2);
  559. TEST_VERIFY (memcmp (backing, "1\0@@", 4) == 0);
  560. }
  561. {
  562. memset (backing, '@', sizeof (backing));
  563. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  564. const char *p = alloc_buffer_copy_string (&buf, "12");
  565. TEST_VERIFY (p == backing);
  566. TEST_VERIFY (strcmp (p, "12") == 0);
  567. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  568. TEST_VERIFY (alloc_buffer_size (&buf) == 1);
  569. TEST_VERIFY (memcmp (backing, "12\0@", 4) == 0);
  570. }
  571. {
  572. memset (backing, '@', sizeof (backing));
  573. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  574. const char *p = alloc_buffer_copy_string (&buf, "123");
  575. TEST_VERIFY (p == backing);
  576. TEST_VERIFY (strcmp (p, "123") == 0);
  577. TEST_VERIFY (!alloc_buffer_has_failed (&buf));
  578. TEST_VERIFY (alloc_buffer_size (&buf) == 0);
  579. TEST_VERIFY (memcmp (backing, "123", 4) == 0);
  580. }
  581. {
  582. memset (backing, '@', sizeof (backing));
  583. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  584. TEST_VERIFY (alloc_buffer_copy_string (&buf, "1234") == NULL);
  585. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  586. TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0);
  587. }
  588. {
  589. memset (backing, '@', sizeof (backing));
  590. struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
  591. TEST_VERIFY (alloc_buffer_copy_string (&buf, "12345") == NULL);
  592. TEST_VERIFY (alloc_buffer_has_failed (&buf));
  593. TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0);
  594. }
  595. }
  596. static int
  597. do_test (void)
  598. {
  599. test_empty (alloc_buffer_create (NULL, 0));
  600. test_empty (alloc_buffer_create ((char *) "", 0));
  601. test_empty (alloc_buffer_create ((void *) 1, 0));
  602. {
  603. void *ptr = (void *) ""; /* Cannot be freed. */
  604. struct alloc_buffer buf = alloc_buffer_allocate (1, &ptr);
  605. test_size_1 (buf);
  606. free (ptr); /* Should have been overwritten. */
  607. }
  608. {
  609. void *ptr= (void *) ""; /* Cannot be freed. */
  610. struct alloc_buffer buf = alloc_buffer_allocate (2, &ptr);
  611. test_size_2 (buf);
  612. free (ptr); /* Should have been overwritten. */
  613. }
  614. test_misaligned (0);
  615. test_misaligned (0xc7);
  616. test_misaligned (0xff);
  617. test_large_misaligned ();
  618. test_large ();
  619. test_copy_bytes ();
  620. test_copy_string ();
  621. return 0;
  622. }
  623. #include <support/test-driver.c>