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. */
34struct 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. */
43static void
44test_empty_array (struct alloc_buffer refbuf)
45{
46 bool refbuf_failed = alloc_buffer_has_failed (buf: &refbuf);
47 if (test_verbose)
48 printf (format: "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. */
86static void
87test_impossible_array (struct alloc_buffer refbuf)
88{
89 if (test_verbose)
90 printf (format: "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 (format: "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. */
132static void
133test_after_failure (struct alloc_buffer refbuf)
134{
135 if (test_verbose)
136 printf (format: "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: &buf, b: 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
188static void
189test_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: &buf, b: 17);
201 test_after_failure (refbuf: buf);
202 }
203 {
204 struct alloc_buffer buf = refbuf;
205 TEST_VERIFY (alloc_buffer_alloc (&buf, char) == NULL);
206 test_after_failure (refbuf: buf);
207 }
208 {
209 struct alloc_buffer buf = refbuf;
210 TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL);
211 test_after_failure (refbuf: buf);
212 }
213 {
214 struct alloc_buffer buf = refbuf;
215 TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL);
216 test_after_failure (refbuf: buf);
217 }
218 {
219 struct alloc_buffer buf = refbuf;
220 TEST_VERIFY (alloc_buffer_alloc_array (&buf, char, 1) == NULL);
221 test_after_failure (refbuf: buf);
222 }
223 {
224 struct alloc_buffer buf = refbuf;
225 TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, 1) == NULL);
226 test_after_failure (refbuf: 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 (refbuf: buf);
232 }
233}
234
235static void
236test_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: &buf, b: 17);
247 TEST_VERIFY (!alloc_buffer_has_failed (&buf));
248 test_empty (refbuf: 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 (refbuf: 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 (refbuf: 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 (refbuf: buf);
275 }
276 {
277 struct alloc_buffer buf = refbuf;
278 TEST_VERIFY (alloc_buffer_alloc (&buf, double) == NULL);
279 test_after_failure (refbuf: buf);
280 }
281 {
282 struct alloc_buffer buf = refbuf;
283 TEST_VERIFY (alloc_buffer_alloc (&buf, struct twelve) == NULL);
284 test_after_failure (refbuf: buf);
285 }
286 {
287 struct alloc_buffer buf = refbuf;
288 TEST_VERIFY (alloc_buffer_alloc_array (&buf, short, 1) == NULL);
289 test_after_failure (refbuf: buf);
290 }
291 {
292 struct alloc_buffer buf = refbuf;
293 TEST_VERIFY (alloc_buffer_alloc_array (&buf, double, 1) == NULL);
294 test_after_failure (refbuf: 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 (refbuf: buf);
300 }
301}
302
303static void
304test_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: &buf, b: '@');
316 TEST_VERIFY (!alloc_buffer_has_failed (&buf));
317 test_size_1 (refbuf: 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 (refbuf: 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 (refbuf: 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 (refbuf: 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 (refbuf: 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 (refbuf: buf);
365 }
366 TEST_VERIFY (memcmp (alloc_buffer_next (&refbuf, void), "12", 2) == 0);
367}
368
369static void
370test_misaligned (char pad)
371{
372 enum { SIZE = 23 };
373 char *backing = xmalloc (n: SIZE + 2);
374 backing[0] = ~pad;
375 backing[SIZE + 1] = pad;
376 struct alloc_buffer refbuf = alloc_buffer_create (start: backing + 1, size: 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 (ptr: backing);
435}
436
437/* Check that overflow during alignment is handled properly. */
438static void
439test_large_misaligned (void)
440{
441 uintptr_t minus1 = -1;
442 uintptr_t start = minus1 & ~0xfe;
443 struct alloc_buffer refbuf = alloc_buffer_create (start: (void *) start, size: 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 (refbuf: 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 (refbuf: buf);
462 }
463}
464
465/* Check behavior of large allocations. */
466static void
467test_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 (refbuf: 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 (refbuf: 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 (refbuf: buf);
525 }
526}
527
528static void
529test_copy_bytes (void)
530{
531 char backing[4];
532 {
533 memset (backing, '@', sizeof (backing));
534 struct alloc_buffer buf = alloc_buffer_create (start: backing, size: sizeof (backing));
535 alloc_buffer_copy_bytes (buf: &buf, src: "1", size: 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 (start: backing, size: sizeof (backing));
543 alloc_buffer_copy_bytes (buf: &buf, src: "12", size: 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 (start: backing, size: sizeof (backing));
551 alloc_buffer_copy_bytes (buf: &buf, src: "1234", size: 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 (start: backing, size: sizeof (backing));
559 alloc_buffer_copy_bytes (buf: &buf, src: "1234", size: 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 (start: backing, size: sizeof (backing));
566 alloc_buffer_copy_bytes (buf: &buf, src: "1234", size: -1);
567 TEST_VERIFY (alloc_buffer_has_failed (&buf));
568 TEST_VERIFY (memcmp (backing, "@@@@", 4) == 0);
569 }
570}
571
572static void
573test_copy_string (void)
574{
575 char backing[4];
576 {
577 memset (backing, '@', sizeof (backing));
578 struct alloc_buffer buf = alloc_buffer_create (start: backing, size: sizeof (backing));
579 const char *p = alloc_buffer_copy_string (buf: &buf, src: "");
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 (start: backing, size: sizeof (backing));
589 const char *p = alloc_buffer_copy_string (buf: &buf, src: "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 (start: backing, size: sizeof (backing));
599 const char *p = alloc_buffer_copy_string (buf: &buf, src: "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 (start: backing, size: sizeof (backing));
609 const char *p = alloc_buffer_copy_string (buf: &buf, src: "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 (start: backing, size: 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 (start: backing, size: 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
632static int
633do_test (void)
634{
635 test_empty (refbuf: alloc_buffer_create (NULL, size: 0));
636 test_empty (refbuf: alloc_buffer_create (start: (char *) "", size: 0));
637 test_empty (refbuf: alloc_buffer_create (start: (void *) 1, size: 0));
638
639 {
640 void *ptr = (void *) ""; /* Cannot be freed. */
641 struct alloc_buffer buf = alloc_buffer_allocate (size: 1, pptr: &ptr);
642 test_size_1 (refbuf: buf);
643 free (ptr: ptr); /* Should have been overwritten. */
644 }
645
646 {
647 void *ptr= (void *) ""; /* Cannot be freed. */
648 struct alloc_buffer buf = alloc_buffer_allocate (size: 2, pptr: &ptr);
649 test_size_2 (refbuf: buf);
650 free (ptr: ptr); /* Should have been overwritten. */
651 }
652
653 test_misaligned (pad: 0);
654 test_misaligned (pad: 0xc7);
655 test_misaligned (pad: 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

source code of glibc/malloc/tst-alloc_buffer.c