123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665 |
- /* Tests for struct alloc_buffer.
- Copyright (C) 2017-2019 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- The GNU C Library is free software; you can redistribute it and/or
- modify it under the terms of the GNU Lesser General Public
- License as published by the Free Software Foundation; either
- version 2.1 of the License, or (at your option) any later version.
- The GNU C Library is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- Lesser General Public License for more details.
- You should have received a copy of the GNU Lesser General Public
- License along with the GNU C Library; if not, see
- <http://www.gnu.org/licenses/>. */
- #include <arpa/inet.h>
- #include <alloc_buffer.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <support/check.h>
- #include <support/support.h>
- #include <support/test-driver.h>
- /* Return true if PTR is sufficiently aligned for TYPE. */
- #define IS_ALIGNED(ptr, type) \
- ((((uintptr_t) ptr) & (__alloc_buffer_assert_align (__alignof (type)) - 1)) \
- == 0)
- /* Structure with non-power-of-two size. */
- struct twelve
- {
- uint32_t buffer[3] __attribute__ ((aligned (4)));
- };
- _Static_assert (sizeof (struct twelve) == 12, "struct twelve");
- _Static_assert (__alignof__ (struct twelve) == 4, "struct twelve");
- /* Check for success obtaining empty arrays. Does not assume the
- buffer is empty. */
- static void
- test_empty_array (struct alloc_buffer refbuf)
- {
- bool refbuf_failed = alloc_buffer_has_failed (&refbuf);
- if (test_verbose)
- printf ("info: %s: current=0x%llx end=0x%llx refbuf_failed=%d\n",
- __func__, (unsigned long long) refbuf.__alloc_buffer_current,
- (unsigned long long) refbuf.__alloc_buffer_end, refbuf_failed);
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY ((alloc_buffer_alloc_bytes (&buf, 0) == NULL)
- == refbuf_failed);
- TEST_VERIFY (alloc_buffer_has_failed (&buf) == refbuf_failed);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY ((alloc_buffer_alloc_array (&buf, char, 0) == NULL)
- == refbuf_failed);
- TEST_VERIFY (alloc_buffer_has_failed (&buf) == refbuf_failed);
- }
- /* The following tests can fail due to the need for aligning the
- returned pointer. */
- {
- struct alloc_buffer buf = refbuf;
- bool expect_failure = refbuf_failed
- || !IS_ALIGNED (alloc_buffer_next (&buf, void), double);
- double *ptr = alloc_buffer_alloc_array (&buf, double, 0);
- TEST_VERIFY (IS_ALIGNED (ptr, double));
- TEST_VERIFY ((ptr == NULL) == expect_failure);
- TEST_VERIFY (alloc_buffer_has_failed (&buf) == expect_failure);
- }
- {
- struct alloc_buffer buf = refbuf;
- bool expect_failure = refbuf_failed
- || !IS_ALIGNED (alloc_buffer_next (&buf, void), struct twelve);
- struct twelve *ptr = alloc_buffer_alloc_array (&buf, struct twelve, 0);
- TEST_VERIFY (IS_ALIGNED (ptr, struct twelve));
- TEST_VERIFY ((ptr == NULL) == expect_failure);
- TEST_VERIFY (alloc_buffer_has_failed (&buf) == expect_failure);
- }
- }
- /* Test allocation of impossibly large arrays. */
- static void
- test_impossible_array (struct alloc_buffer refbuf)
- {
- if (test_verbose)
- printf ("info: %s: current=0x%llx end=0x%llx\n",
- __func__, (unsigned long long) refbuf.__alloc_buffer_current,
- (unsigned long long) refbuf.__alloc_buffer_end);
- static const size_t counts[] =
- { SIZE_MAX, SIZE_MAX - 1, SIZE_MAX - 2, SIZE_MAX - 3, SIZE_MAX - 4,
- SIZE_MAX / 2, SIZE_MAX / 2 + 1, SIZE_MAX / 2 - 1, 0};
- for (int i = 0; counts[i] != 0; ++i)
- {
- size_t count = counts[i];
- if (test_verbose)
- printf ("info: %s: count=%zu\n", __func__, count);
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_bytes (&buf, count) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, count) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, short, count) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, count) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, count)
- == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- }
- }
- /* Check for failure to obtain anything from a failed buffer. */
- static void
- test_after_failure (struct alloc_buffer refbuf)
- {
- if (test_verbose)
- printf ("info: %s: current=0x%llx end=0x%llx\n",
- __func__, (unsigned long long) refbuf.__alloc_buffer_current,
- (unsigned long long) refbuf.__alloc_buffer_end);
- TEST_VERIFY (alloc_buffer_has_failed (&refbuf));
- {
- struct alloc_buffer buf = refbuf;
- alloc_buffer_add_byte (&buf, 17);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc (&buf, char) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- test_impossible_array (refbuf);
- for (int count = 0; count <= 4; ++count)
- {
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_bytes (&buf, count) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, count) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, count) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, count)
- == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- }
- }
- static void
- test_empty (struct alloc_buffer refbuf)
- {
- TEST_VERIFY (alloc_buffer_size (&refbuf) == 0);
- if (alloc_buffer_next (&refbuf, void) != NULL)
- TEST_VERIFY (!alloc_buffer_has_failed (&refbuf));
- test_empty_array (refbuf);
- test_impossible_array (refbuf);
- /* Failure to obtain non-empty objects. */
- {
- struct alloc_buffer buf = refbuf;
- alloc_buffer_add_byte (&buf, 17);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc (&buf, char) == NULL);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, 1) == NULL);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, 1) == NULL);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, 1) == NULL);
- test_after_failure (buf);
- }
- }
- static void
- test_size_1 (struct alloc_buffer refbuf)
- {
- TEST_VERIFY (!alloc_buffer_has_failed (&refbuf));
- TEST_VERIFY (alloc_buffer_size (&refbuf) == 1);
- test_empty_array (refbuf);
- test_impossible_array (refbuf);
- /* Success adding a single byte. */
- {
- struct alloc_buffer buf = refbuf;
- alloc_buffer_add_byte (&buf, 17);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- test_empty (buf);
- }
- TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\x11", 1) == 0);
- {
- struct alloc_buffer buf = refbuf;
- signed char *ptr = alloc_buffer_alloc (&buf, signed char);
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- *ptr = 126;
- test_empty (buf);
- }
- TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\176", 1) == 0);
- {
- struct alloc_buffer buf = refbuf;
- char *ptr = alloc_buffer_alloc_array (&buf, char, 1);
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- *ptr = (char) 253;
- test_empty (buf);
- }
- TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\xfd", 1) == 0);
- /* Failure with larger objects. */
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc (&buf, short) == NULL);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, short, 1) == NULL);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, 1) == NULL);
- test_after_failure (buf);
- }
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct twelve, 1) == NULL);
- test_after_failure (buf);
- }
- }
- static void
- test_size_2 (struct alloc_buffer refbuf)
- {
- TEST_VERIFY (!alloc_buffer_has_failed (&refbuf));
- TEST_VERIFY (alloc_buffer_size (&refbuf) == 2);
- TEST_VERIFY (IS_ALIGNED (alloc_buffer_next (&refbuf, void), short));
- test_empty_array (refbuf);
- test_impossible_array (refbuf);
- /* Success adding two bytes. */
- {
- struct alloc_buffer buf = refbuf;
- alloc_buffer_add_byte (&buf, '@');
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- test_size_1 (buf);
- }
- TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "@\xfd", 2) == 0);
- {
- struct alloc_buffer buf = refbuf;
- signed char *ptr = alloc_buffer_alloc (&buf, signed char);
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- *ptr = 'A';
- test_size_1 (buf);
- }
- TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "A\xfd", 2) == 0);
- {
- struct alloc_buffer buf = refbuf;
- char *ptr = alloc_buffer_alloc_array (&buf, char, 1);
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- *ptr = 'B';
- test_size_1 (buf);
- }
- TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "B\xfd", 2) == 0);
- {
- struct alloc_buffer buf = refbuf;
- unsigned short *ptr = alloc_buffer_alloc (&buf, unsigned short);
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (IS_ALIGNED (ptr, unsigned short));
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- *ptr = htons (0x12f4);
- test_empty (buf);
- }
- TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\x12\xf4", 2) == 0);
- {
- struct alloc_buffer buf = refbuf;
- unsigned short *ptr = alloc_buffer_alloc_array (&buf, unsigned short, 1);
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (IS_ALIGNED (ptr, unsigned short));
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- *ptr = htons (0x13f5);
- test_empty (buf);
- }
- TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "\x13\xf5", 2) == 0);
- {
- struct alloc_buffer buf = refbuf;
- char *ptr = alloc_buffer_alloc_array (&buf, char, 2);
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- memcpy (ptr, "12", 2);
- test_empty (buf);
- }
- TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "12", 2) == 0);
- }
- static void
- test_misaligned (char pad)
- {
- enum { SIZE = 23 };
- char *backing = xmalloc (SIZE + 2);
- backing[0] = ~pad;
- backing[SIZE + 1] = pad;
- struct alloc_buffer refbuf = alloc_buffer_create (backing + 1, SIZE);
- {
- struct alloc_buffer buf = refbuf;
- short *ptr = alloc_buffer_alloc_array (&buf, short, SIZE / sizeof (short));
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (IS_ALIGNED (ptr, short));
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- for (int i = 0; i < SIZE / sizeof (short); ++i)
- ptr[i] = htons (0xff01 + i);
- TEST_VERIFY (memcmp (ptr,
- "\xff\x01\xff\x02\xff\x03\xff\x04"
- "\xff\x05\xff\x06\xff\x07\xff\x08"
- "\xff\x09\xff\x0a\xff\x0b", 22) == 0);
- }
- {
- struct alloc_buffer buf = refbuf;
- uint32_t *ptr = alloc_buffer_alloc_array
- (&buf, uint32_t, SIZE / sizeof (uint32_t));
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (IS_ALIGNED (ptr, uint32_t));
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- for (int i = 0; i < SIZE / sizeof (uint32_t); ++i)
- ptr[i] = htonl (0xf1e2d301 + i);
- TEST_VERIFY (memcmp (ptr,
- "\xf1\xe2\xd3\x01\xf1\xe2\xd3\x02"
- "\xf1\xe2\xd3\x03\xf1\xe2\xd3\x04"
- "\xf1\xe2\xd3\x05", 20) == 0);
- }
- {
- struct alloc_buffer buf = refbuf;
- struct twelve *ptr = alloc_buffer_alloc (&buf, struct twelve);
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (IS_ALIGNED (ptr, struct twelve));
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- ptr->buffer[0] = htonl (0x11223344);
- ptr->buffer[1] = htonl (0x55667788);
- ptr->buffer[2] = htonl (0x99aabbcc);
- TEST_VERIFY (memcmp (ptr,
- "\x11\x22\x33\x44"
- "\x55\x66\x77\x88"
- "\x99\xaa\xbb\xcc", 12) == 0);
- }
- {
- static const double nums[] = { 1, 2 };
- struct alloc_buffer buf = refbuf;
- double *ptr = alloc_buffer_alloc_array (&buf, double, 2);
- TEST_VERIFY_EXIT (ptr != NULL);
- TEST_VERIFY (IS_ALIGNED (ptr, double));
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- ptr[0] = nums[0];
- ptr[1] = nums[1];
- TEST_VERIFY (memcmp (ptr, nums, sizeof (nums)) == 0);
- }
- /* Verify that padding was not overwritten. */
- TEST_VERIFY (backing[0] == (char) ~pad);
- TEST_VERIFY (backing[SIZE + 1] == pad);
- free (backing);
- }
- /* Check that overflow during alignment is handled properly. */
- static void
- test_large_misaligned (void)
- {
- uintptr_t minus1 = -1;
- uintptr_t start = minus1 & ~0xfe;
- struct alloc_buffer refbuf = alloc_buffer_create ((void *) start, 16);
- TEST_VERIFY (!alloc_buffer_has_failed (&refbuf));
- struct __attribute__ ((aligned (256))) align256
- {
- int dymmy;
- };
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc (&buf, struct align256) == NULL);
- test_after_failure (buf);
- }
- for (int count = 0; count < 3; ++count)
- {
- struct alloc_buffer buf = refbuf;
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, struct align256, count)
- == NULL);
- test_after_failure (buf);
- }
- }
- /* Check behavior of large allocations. */
- static void
- test_large (void)
- {
- {
- /* Allocation which wraps around. */
- struct alloc_buffer buf = { 1, SIZE_MAX };
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, SIZE_MAX) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- /* Successful very large allocation. */
- struct alloc_buffer buf = { 1, SIZE_MAX };
- uintptr_t val = (uintptr_t) alloc_buffer_alloc_array
- (&buf, char, SIZE_MAX - 1);
- TEST_VERIFY (val == 1);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- test_empty (buf);
- }
- {
- typedef char __attribute__ ((aligned (2))) char2;
- /* Overflow in array size computation. */
- struct alloc_buffer buf = { 1, SIZE_MAX };
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, char2, SIZE_MAX - 1) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- /* Successful allocation after alignment. */
- buf = (struct alloc_buffer) { 1, SIZE_MAX };
- uintptr_t val = (uintptr_t) alloc_buffer_alloc_array
- (&buf, char2, SIZE_MAX - 2);
- TEST_VERIFY (val == 2);
- test_empty (buf);
- /* Alignment behavior near the top of the address space. */
- buf = (struct alloc_buffer) { SIZE_MAX, SIZE_MAX };
- TEST_VERIFY (alloc_buffer_next (&buf, char2) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- buf = (struct alloc_buffer) { SIZE_MAX, SIZE_MAX };
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, char2, 0) == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- }
- {
- typedef short __attribute__ ((aligned (2))) short2;
- /* Test overflow in size computation. */
- struct alloc_buffer buf = { 1, SIZE_MAX };
- TEST_VERIFY (alloc_buffer_alloc_array (&buf, short2, SIZE_MAX / 2)
- == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- /* A slightly smaller array fits within the allocation. */
- buf = (struct alloc_buffer) { 2, SIZE_MAX - 1 };
- uintptr_t val = (uintptr_t) alloc_buffer_alloc_array
- (&buf, short2, SIZE_MAX / 2 - 1);
- TEST_VERIFY (val == 2);
- test_empty (buf);
- }
- }
- static void
- test_copy_bytes (void)
- {
- char backing[4];
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- alloc_buffer_copy_bytes (&buf, "1", 1);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- TEST_VERIFY (alloc_buffer_size (&buf) == 3);
- TEST_VERIFY (memcmp (backing, "1@@@", 4) == 0);
- }
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- alloc_buffer_copy_bytes (&buf, "12", 3);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- TEST_VERIFY (alloc_buffer_size (&buf) == 1);
- TEST_VERIFY (memcmp (backing, "12\0@", 4) == 0);
- }
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- alloc_buffer_copy_bytes (&buf, "1234", 4);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- TEST_VERIFY (alloc_buffer_size (&buf) == 0);
- TEST_VERIFY (memcmp (backing, "1234", 4) == 0);
- }
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- alloc_buffer_copy_bytes (&buf, "1234", 5);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0);
- }
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- alloc_buffer_copy_bytes (&buf, "1234", -1);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0);
- }
- }
- static void
- test_copy_string (void)
- {
- char backing[4];
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- const char *p = alloc_buffer_copy_string (&buf, "");
- TEST_VERIFY (p == backing);
- TEST_VERIFY (strcmp (p, "") == 0);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- TEST_VERIFY (alloc_buffer_size (&buf) == 3);
- TEST_VERIFY (memcmp (backing, "\0@@@", 4) == 0);
- }
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- const char *p = alloc_buffer_copy_string (&buf, "1");
- TEST_VERIFY (p == backing);
- TEST_VERIFY (strcmp (p, "1") == 0);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- TEST_VERIFY (alloc_buffer_size (&buf) == 2);
- TEST_VERIFY (memcmp (backing, "1\0@@", 4) == 0);
- }
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- const char *p = alloc_buffer_copy_string (&buf, "12");
- TEST_VERIFY (p == backing);
- TEST_VERIFY (strcmp (p, "12") == 0);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- TEST_VERIFY (alloc_buffer_size (&buf) == 1);
- TEST_VERIFY (memcmp (backing, "12\0@", 4) == 0);
- }
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- const char *p = alloc_buffer_copy_string (&buf, "123");
- TEST_VERIFY (p == backing);
- TEST_VERIFY (strcmp (p, "123") == 0);
- TEST_VERIFY (!alloc_buffer_has_failed (&buf));
- TEST_VERIFY (alloc_buffer_size (&buf) == 0);
- TEST_VERIFY (memcmp (backing, "123", 4) == 0);
- }
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- TEST_VERIFY (alloc_buffer_copy_string (&buf, "1234") == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0);
- }
- {
- memset (backing, '@', sizeof (backing));
- struct alloc_buffer buf = alloc_buffer_create (backing, sizeof (backing));
- TEST_VERIFY (alloc_buffer_copy_string (&buf, "12345") == NULL);
- TEST_VERIFY (alloc_buffer_has_failed (&buf));
- TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0);
- }
- }
- static int
- do_test (void)
- {
- test_empty (alloc_buffer_create (NULL, 0));
- test_empty (alloc_buffer_create ((char *) "", 0));
- test_empty (alloc_buffer_create ((void *) 1, 0));
- {
- void *ptr = (void *) ""; /* Cannot be freed. */
- struct alloc_buffer buf = alloc_buffer_allocate (1, &ptr);
- test_size_1 (buf);
- free (ptr); /* Should have been overwritten. */
- }
- {
- void *ptr= (void *) ""; /* Cannot be freed. */
- struct alloc_buffer buf = alloc_buffer_allocate (2, &ptr);
- test_size_2 (buf);
- free (ptr); /* Should have been overwritten. */
- }
- test_misaligned (0);
- test_misaligned (0xc7);
- test_misaligned (0xff);
- test_large_misaligned ();
- test_large ();
- test_copy_bytes ();
- test_copy_string ();
- return 0;
- }
- #include <support/test-driver.c>
|