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