The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
talloc_tests.c
Go to the documentation of this file.
1/*
2 * This library is free software; you can redistribute it and/or
3 * modify it under the terms of the GNU Lesser General Public
4 * License as published by the Free Software Foundation; either
5 * version 2.1 of the License, or (at your option) any later version.
6 *
7 * This library is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * Lesser General Public License for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public
13 * License along with this library; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/** Tests for talloc and FreeRADIUS talloc utility functions
18 *
19 * @file src/lib/util/test/talloc_tests.c
20 *
21 * @copyright 2026 Network RADIUS SAS (legal@networkradius.com)
22 */
23#include "acutest.h"
24#include "acutest_helpers.h"
25#include <freeradius-devel/util/talloc.h>
26
27/*
28 * === Core talloc (samba) tests ===
29 */
30
31/*
32 * talloc - basic allocation and parent/child hierarchy
33 */
34static void test_talloc_basic(void)
35{
36 TALLOC_CTX *ctx;
37 int *p;
38 char *s;
39
40 ctx = talloc_init_const("test_basic");
41 TEST_ASSERT(ctx != NULL);
42
43 TEST_CASE("talloc allocates child of context");
44 p = talloc(ctx, int);
45 TEST_ASSERT(p != NULL);
46 TEST_CHECK(talloc_parent(p) == ctx);
47 *p = 42;
48 TEST_CHECK(*p == 42);
49
50 TEST_CASE("talloc_size allocates arbitrary size");
51 s = talloc_size(ctx, 100);
52 TEST_ASSERT(s != NULL);
53 TEST_CHECK(talloc_get_size(s) == 100);
54 TEST_CHECK(talloc_parent(s) == ctx);
55
56 talloc_free(ctx);
57}
58
59/*
60 * talloc_zero - zero-initialized allocation
61 */
62static void test_talloc_zero(void)
63{
64 TALLOC_CTX *ctx;
65 int *p;
66 uint8_t *buf;
67 unsigned int i;
68
69 ctx = talloc_init_const("test_zero");
70
71 TEST_CASE("talloc_zero initializes to zero");
72 p = talloc_zero(ctx, int);
73 TEST_ASSERT(p != NULL);
74 TEST_CHECK(*p == 0);
75
76 TEST_CASE("talloc_zero_size initializes to zero");
77 buf = talloc_zero_size(ctx, 64);
78 TEST_ASSERT(buf != NULL);
79 for (i = 0; i < 64; i++) {
80 TEST_CHECK(buf[i] == 0);
81 }
82
83 talloc_free(ctx);
84}
85
86/*
87 * talloc_array / talloc_zero_array / talloc_realloc
88 */
89static void test_talloc_array(void)
90{
91 TALLOC_CTX *ctx;
92 int *arr;
93 unsigned int i;
94
95 ctx = talloc_init_const("test_array");
96
97 TEST_CASE("talloc_array allocates typed array");
98 arr = talloc_array(ctx, int, 10);
99 TEST_ASSERT(arr != NULL);
100 TEST_CHECK(talloc_get_size(arr) == 10 * sizeof(int));
101 for (i = 0; i < 10; i++) arr[i] = (int)i;
102 for (i = 0; i < 10; i++) TEST_CHECK(arr[i] == (int)i);
103
104 TEST_CASE("talloc_zero_array initializes to zero");
105 arr = talloc_zero_array(ctx, int, 5);
106 TEST_ASSERT(arr != NULL);
107 for (i = 0; i < 5; i++) TEST_CHECK(arr[i] == 0);
108
109 TEST_CASE("talloc_realloc grows array preserving content");
110 arr = talloc_array(ctx, int, 4);
111 for (i = 0; i < 4; i++) arr[i] = (int)(i + 100);
112 arr = talloc_realloc(ctx, arr, int, 8);
113 TEST_ASSERT(arr != NULL);
114 for (i = 0; i < 4; i++) TEST_CHECK(arr[i] == (int)(i + 100));
115 TEST_CHECK(talloc_get_size(arr) == 8 * sizeof(int));
116
117 TEST_CASE("talloc_realloc shrinks array");
118 arr = talloc_realloc(ctx, arr, int, 2);
119 TEST_ASSERT(arr != NULL);
120 TEST_CHECK(arr[0] == 100);
121 TEST_CHECK(arr[1] == 101);
122 TEST_CHECK(talloc_get_size(arr) == 2 * sizeof(int));
123
124 talloc_free(ctx);
125}
126
127/*
128 * talloc_free - recursive free of children
129 */
130static void test_talloc_free(void)
131{
132 TALLOC_CTX *ctx;
133 int *child1, *child2;
134
135 TEST_CASE("talloc_free(NULL) returns -1");
136 TEST_CHECK(talloc_free(NULL) == -1);
137
138 TEST_CASE("talloc_free recursively frees children");
139 ctx = talloc_init_const("test_free");
140 child1 = talloc(ctx, int);
141 TEST_ASSERT(child1 != NULL);
142 child2 = talloc(child1, int);
143 TEST_ASSERT(child2 != NULL);
144 TEST_CHECK(talloc_parent(child2) == child1);
145 TEST_CHECK(talloc_free(ctx) == 0);
146}
147
148/*
149 * talloc_set_name_const / talloc_get_name / talloc_check_name
150 */
151static void test_talloc_naming(void)
152{
153 TALLOC_CTX *ctx;
154 void *p;
155
156 ctx = talloc_init_const("test_naming");
157
158 TEST_CASE("talloc_set_name_const / talloc_get_name roundtrip");
159 p = talloc_size(ctx, 10);
160 talloc_set_name_const(p, "my_chunk");
161 TEST_CHECK(strcmp(talloc_get_name(p), "my_chunk") == 0);
162
163 TEST_CASE("talloc_check_name succeeds on match");
164 TEST_CHECK(talloc_check_name(p, "my_chunk") == p);
165
166 TEST_CASE("talloc_check_name returns NULL on mismatch");
167 TEST_CHECK(talloc_check_name(p, "wrong_name") == NULL);
168
169 TEST_CASE("talloc_named_const sets name at creation");
170 p = talloc_named_const(ctx, 20, "named_chunk");
171 TEST_ASSERT(p != NULL);
172 TEST_CHECK(strcmp(talloc_get_name(p), "named_chunk") == 0);
173
174 talloc_free(ctx);
175}
176
177/*
178 * talloc_parent / talloc_parent_name
179 */
180static void test_talloc_parent(void)
181{
182 TALLOC_CTX *ctx;
183 int *child;
184
185 ctx = talloc_init_const("test_parent");
186
187 TEST_CASE("talloc_parent returns correct parent");
188 child = talloc(ctx, int);
189 TEST_CHECK(talloc_parent(child) == ctx);
190
191 TEST_CASE("talloc_parent_name returns parent's name");
192 TEST_CHECK(strcmp(talloc_parent_name(child), "test_parent") == 0);
193
194 TEST_CASE("talloc_parent of top-level returns NULL context");
195 /*
196 * Top-level contexts allocated with talloc_init have the
197 * null context as parent (or NULL if tracking is off).
198 */
199 {
200 void *parent = talloc_parent(ctx);
201 (void)parent; /* Just verify it doesn't crash */
202 }
203
204 talloc_free(ctx);
205}
206
207/*
208 * talloc_steal - reparent a chunk
209 */
210static void test_talloc_steal(void)
211{
212 TALLOC_CTX *ctx1, *ctx2;
213 int *p;
214 void *ret;
215
216 ctx1 = talloc_init_const("ctx1");
217 ctx2 = talloc_init_const("ctx2");
218
219 TEST_CASE("talloc_steal moves child to new parent");
220 p = talloc(ctx1, int);
221 *p = 99;
222 TEST_CHECK(talloc_parent(p) == ctx1);
223 ret = talloc_steal(ctx2, p);
224 TEST_CHECK(ret == p);
225 TEST_CHECK(talloc_parent(p) == ctx2);
226 TEST_CHECK(*p == 99);
227
228 TEST_CASE("talloc_steal NULL returns NULL");
229 TEST_CHECK(talloc_steal(ctx1, NULL) == NULL);
230
231 TEST_CASE("talloc_steal to NULL reparents to null context");
232 p = talloc(ctx1, int);
233 ret = talloc_steal(NULL, p);
234 TEST_CHECK(ret == p);
235 talloc_free(p); /* must free manually since no parent owns it */
236
237 talloc_free(ctx1);
238 talloc_free(ctx2);
239}
240
241/*
242 * talloc_move - steal and NULL out old pointer
243 */
244static void test_talloc_move(void)
245{
246 TALLOC_CTX *ctx1, *ctx2;
247 int *p, *moved;
248
249 ctx1 = talloc_init_const("ctx1");
250 ctx2 = talloc_init_const("ctx2");
251
252 TEST_CASE("talloc_move transfers ownership and NULLs source");
253 p = talloc(ctx1, int);
254 *p = 77;
255 moved = talloc_move(ctx2, &p);
256 TEST_ASSERT(moved != NULL);
257 TEST_CHECK(*moved == 77);
258 TEST_CHECK(p == NULL);
259 TEST_CHECK(talloc_parent(moved) == ctx2);
260
261 talloc_free(ctx1);
262 talloc_free(ctx2);
263}
264
265/*
266 * talloc_reference / talloc_unlink / talloc_reference_count
267 */
268static void test_talloc_reference(void)
269{
270 TALLOC_CTX *ctx1, *ctx2;
271 char *str;
272 void *ref;
273
274 ctx1 = talloc_init_const("ctx1");
275 ctx2 = talloc_init_const("ctx2");
276
277 TEST_CASE("talloc_reference creates a reference");
278 str = talloc_strdup(ctx1, "shared");
279 ref = talloc_reference(ctx2, str);
280 TEST_CHECK(ref != NULL);
281 TEST_CHECK(talloc_reference_count(str) == 1);
282
283 TEST_CASE("talloc_unlink removes the reference");
284 TEST_CHECK(talloc_unlink(ctx2, str) == 0);
285 TEST_CHECK(talloc_reference_count(str) == 0);
286
287 TEST_CASE("Multiple references increment count");
288 talloc_reference(ctx2, str);
289 talloc_reference(ctx2, str);
290 TEST_CHECK(talloc_reference_count(str) >= 2);
291
292 talloc_free(ctx1);
293 talloc_free(ctx2);
294}
295
296/*
297 * talloc_set_destructor - native talloc destructors
298 */
300
301static int native_destructor(int *ptr)
302{
303 TEST_ASSERT(*ptr == 1);
304 *ptr = 0;
306 return 0;
307}
308
310{
311 TALLOC_CTX *ctx;
312 int *p;
313
314 ctx = talloc_init_const("test_destructor");
315
316 TEST_CASE("Destructor called on free");
318 p = talloc(ctx, int);
319 *p = 1;
320 talloc_set_destructor(p, native_destructor);
321 talloc_free(p);
323
324 TEST_CASE("Destructor returning -1 prevents free");
325
326 /*
327 * We can't easily test this without risking a leak,
328 * so just verify the destructor fires on parent free.
329 */
331 p = talloc(ctx, int);
332 *p = 1;
333 talloc_set_destructor(p, native_destructor);
334 talloc_free(ctx);
336}
337
338/*
339 * talloc_strdup / talloc_strndup (base samba versions,
340 * which are remapped to talloc_typed_strdup/strndup by the header)
341 */
342static void test_talloc_strdup(void)
343{
344 TALLOC_CTX *ctx;
345 char *s;
346
347 ctx = talloc_init_const("test_strdup");
348
349 TEST_CASE("talloc_strdup duplicates string");
350 s = talloc_strdup(ctx, "hello");
351 TEST_ASSERT(s != NULL);
352 TEST_CHECK(strcmp(s, "hello") == 0);
353 TEST_CHECK(talloc_parent(s) == ctx);
354
355 TEST_CASE("talloc_strndup limits length");
356 s = talloc_strndup(ctx, "hello world", 5);
357 TEST_ASSERT(s != NULL);
358 TEST_CHECK(strcmp(s, "hello") == 0);
359
360 TEST_CASE("talloc_strdup of NULL returns NULL");
361 s = talloc_strdup(ctx, NULL);
362 TEST_CHECK(s == NULL);
363
364 talloc_free(ctx);
365}
366
367/*
368 * talloc_asprintf / talloc_asprintf_append / talloc_asprintf_append_buffer
369 */
370static void test_talloc_asprintf(void)
371{
372 TALLOC_CTX *ctx;
373 char *s;
374
375 ctx = talloc_init_const("test_asprintf");
376
377 TEST_CASE("talloc_asprintf formats string");
378 s = talloc_asprintf(ctx, "num=%d str=%s", 42, "foo");
379 TEST_ASSERT(s != NULL);
380 TEST_CHECK(strcmp(s, "num=42 str=foo") == 0);
381
382 TEST_CASE("talloc_asprintf_append appends at string end");
383 s = talloc_strdup(ctx, "hello");
384 s = talloc_asprintf_append(s, " %s", "world");
385 TEST_ASSERT(s != NULL);
386 TEST_CHECK(strcmp(s, "hello world") == 0);
387
388 TEST_CASE("talloc_asprintf_append_buffer appends at buffer end");
389 s = talloc_strdup(ctx, "abc");
390 s = talloc_asprintf_append_buffer(s, "def");
391 TEST_ASSERT(s != NULL);
392 TEST_CHECK(strcmp(s, "abcdef") == 0);
393
394 talloc_free(ctx);
395}
396
397/*
398 * talloc_pool - suballocations from a pool
399 */
400static void test_talloc_pool(void)
401{
402 TALLOC_CTX *pool;
403 int *a, *b, *c;
404
405 TEST_CASE("talloc_pool creates a pool context");
406 pool = talloc_pool(NULL, 1024);
407 TEST_ASSERT(pool != NULL);
408
409 TEST_CASE("Allocations from pool succeed");
410 a = talloc(pool, int);
411 b = talloc(pool, int);
412 c = talloc(pool, int);
413 TEST_ASSERT(a != NULL);
414 TEST_ASSERT(b != NULL);
415 TEST_ASSERT(c != NULL);
416 *a = 1; *b = 2; *c = 3;
417 TEST_CHECK(*a == 1);
418 TEST_CHECK(*b == 2);
419 TEST_CHECK(*c == 3);
420
421 TEST_CASE("Pool children have pool as parent");
422 TEST_CHECK(talloc_parent(a) == pool);
423 TEST_CHECK(talloc_parent(b) == pool);
424
425 talloc_free(pool);
426}
427
428/*
429 * talloc_free_children - free all children but keep parent
430 */
432{
433 TALLOC_CTX *ctx;
434 int *p;
435
436 ctx = talloc_init_const("test_free_children");
437
438 TEST_CASE("talloc_free_children frees all children");
439
440 p = talloc(ctx, int);
441 TEST_CHECK(p != NULL);
442 p = talloc(ctx, int);
443 TEST_CHECK(p != NULL);
444 p = talloc(ctx, int);
445 TEST_CHECK(p != NULL);
446
447 TEST_CHECK(talloc_total_blocks(ctx) == 4); /* ctx + 3 children */
448
449 talloc_free_children(ctx);
450 TEST_CHECK(talloc_total_blocks(ctx) == 1); /* just ctx */
451
452 TEST_CASE("Context is still usable after free_children");
453 p = talloc(ctx, int);
454 TEST_ASSERT(p != NULL);
455 *p = 123;
456 TEST_CHECK(*p == 123);
457
458 talloc_free(ctx);
459}
460
461/*
462 * talloc_total_size / talloc_total_blocks
463 */
464static void test_talloc_total_size(void)
465{
466 TALLOC_CTX *ctx;
467 size_t total_size, total_blocks;
468
469 ctx = talloc_init_const("test_total");
470
471 TEST_CASE("Empty context has size 0 and 1 block");
472 TEST_CHECK(talloc_total_size(ctx) == 0);
473 TEST_CHECK(talloc_total_blocks(ctx) == 1);
474
475 TEST_CASE("Allocations increase totals");
476 talloc_size(ctx, 100);
477 talloc_size(ctx, 200);
478 total_size = talloc_total_size(ctx);
479 total_blocks = talloc_total_blocks(ctx);
480 TEST_CHECK(total_size >= 300);
481 TEST_CHECK(total_blocks == 3); /* ctx + 2 children */
482
483 TEST_CASE("Nested children counted in totals");
484 {
485 void *child = talloc_size(ctx, 50);
486 talloc_size(child, 25);
487 }
488 TEST_CHECK(talloc_total_size(ctx) >= 375);
489 TEST_CHECK(talloc_total_blocks(ctx) == 5);
490
491 talloc_free(ctx);
492}
493
494/*
495 * talloc_get_size - get chunk data size
496 */
497static void test_talloc_get_size(void)
498{
499 TALLOC_CTX *ctx;
500 void *p;
501
502 ctx = talloc_init_const("test_get_size");
503
504 TEST_CASE("talloc_get_size returns requested size");
505 p = talloc_size(ctx, 42);
506 TEST_CHECK(talloc_get_size(p) == 42);
507
508 TEST_CASE("talloc_get_size of NULL returns 0");
509 TEST_CHECK(talloc_get_size(NULL) == 0);
510
511 TEST_CASE("talloc_get_size after realloc returns new size");
512 p = talloc_realloc_size(ctx, p, 100);
513 TEST_CHECK(talloc_get_size(p) == 100);
514
515 talloc_free(ctx);
516}
517
518/*
519 * talloc_find_parent_byname - walk parent chain looking for name
520 */
522{
523 TALLOC_CTX *root, *mid;
524 int *leaf;
525 void *found;
526
527 root = talloc_named_const(NULL, 0, "root_ctx");
528 mid = talloc_named_const(root, 0, "mid_ctx");
529 leaf = talloc(mid, int);
530
531 TEST_CASE("Find existing parent by name");
532 found = talloc_find_parent_byname(leaf, "root_ctx");
533 TEST_CHECK(found == root);
534
535 found = talloc_find_parent_byname(leaf, "mid_ctx");
536 TEST_CHECK(found == mid);
537
538 TEST_CASE("Return NULL for non-existent parent name");
539 found = talloc_find_parent_byname(leaf, "nonexistent");
540 TEST_CHECK(found == NULL);
541
542 talloc_free(root);
543}
544
545/*
546 * talloc_is_parent - check if ptr is an ancestor
547 */
548static void test_talloc_is_parent(void)
549{
550 TALLOC_CTX *root, *mid;
551 int *leaf;
552
553 root = talloc_init_const("root");
554 mid = talloc(root, char);
555 leaf = talloc(mid, int);
556
557 TEST_CASE("Direct parent is parent");
558 TEST_CHECK(talloc_is_parent(leaf, mid) == 1);
559
560 TEST_CASE("Grandparent is parent");
561 TEST_CHECK(talloc_is_parent(leaf, root) == 1);
562
563 TEST_CASE("Non-parent is not parent");
564 {
565 TALLOC_CTX *other = talloc_init_const("other");
566 TEST_CHECK(talloc_is_parent(leaf, other) == 0);
567 talloc_free(other);
568 }
569
570 talloc_free(root);
571}
572
573/*
574 * talloc_reparent - reparent with explicit old parent
575 */
576static void test_talloc_reparent(void)
577{
578 TALLOC_CTX *old_parent, *new_parent;
579 int *p;
580 void *ret;
581
582 old_parent = talloc_init_const("old");
583 new_parent = talloc_init_const("new");
584
585 TEST_CASE("talloc_reparent moves from old to new parent");
586 p = talloc(old_parent, int);
587 *p = 55;
588 ret = talloc_reparent(old_parent, new_parent, p);
589 TEST_CHECK(ret == p);
590 TEST_CHECK(talloc_parent(p) == new_parent);
591 TEST_CHECK(*p == 55);
592
593 TEST_CASE("talloc_reparent NULL returns NULL");
594 ret = talloc_reparent(old_parent, new_parent, NULL);
595 TEST_CHECK(ret == NULL);
596
597 talloc_free(old_parent);
598 talloc_free(new_parent);
599}
600
601/*
602 * talloc_memdup - duplicate memory
603 */
604static void test_talloc_memdup(void)
605{
606 TALLOC_CTX *ctx;
607 uint8_t src[] = {0x01, 0x02, 0x03, 0x04};
608 uint8_t *dup;
609
610 ctx = talloc_init_const("test_memdup");
611
612 TEST_CASE("talloc_memdup duplicates bytes");
613 dup = talloc_memdup(ctx, src, sizeof(src));
614 TEST_ASSERT(dup != NULL);
615 TEST_CHECK(memcmp(dup, src, sizeof(src)) == 0);
616 TEST_CHECK(talloc_get_size(dup) == sizeof(src));
617 TEST_CHECK(talloc_parent(dup) == ctx);
618
619 talloc_free(ctx);
620}
621
622/*
623 * talloc hierarchy depth - deep nesting
624 */
626{
627 TALLOC_CTX *root;
628 void *current;
629 int i;
630
631 root = talloc_init_const("deep_root");
632 current = root;
633
634 TEST_CASE("Deep hierarchy (100 levels) works");
635 for (i = 0; i < 100; i++) {
636 current = talloc_size(current, 16);
637 TEST_ASSERT(current != NULL);
638 }
639
640 TEST_CASE("Total blocks counts all levels");
641 TEST_CHECK(talloc_total_blocks(root) == 101); /* root + 100 children */
642
643 TEST_CASE("Free cleans up entire hierarchy");
644 TEST_CHECK(talloc_free(root) == 0);
645}
646
647/*
648 * talloc_strndup_append / talloc_strndup_append_buffer
649 */
651{
652 TALLOC_CTX *ctx;
653 char *s;
654
655 ctx = talloc_init_const("test_strndup_append");
656
657 TEST_CASE("talloc_strndup_append appends limited length");
658 s = talloc_strdup(ctx, "hello");
659 s = talloc_strndup_append(s, " world!!", 6);
660 TEST_ASSERT(s != NULL);
661 TEST_CHECK(strcmp(s, "hello world") == 0);
662
663 TEST_CASE("talloc_strndup_append_buffer appends at buffer end");
664 s = talloc_strdup(ctx, "abc");
665 s = talloc_strndup_append_buffer(s, "defgh", 3);
666 TEST_ASSERT(s != NULL);
667 TEST_CHECK(strcmp(s, "abcdef") == 0);
668
669 talloc_free(ctx);
670}
671
672/*
673 * talloc_increase_ref_count
674 */
676{
677 TALLOC_CTX *ctx;
678 char *str;
679 int ret;
680
681 ctx = talloc_init_const("test_ref_count");
682
683 TEST_CASE("increase_ref_count succeeds");
684 str = talloc_strdup(ctx, "refcounted");
685 ret = talloc_increase_ref_count(str);
686 TEST_CHECK(ret == 0);
687 TEST_CHECK(talloc_reference_count(str) == 1);
688
689 TEST_CASE("Multiple increases stack");
690 ret = talloc_increase_ref_count(str);
691 TEST_CHECK(ret == 0);
692 TEST_CHECK(talloc_reference_count(str) == 2);
693
694 /*
695 * And then decrease it to be safe.
696 */
697 ret = talloc_decrease_ref_count(str);
698 TEST_CHECK(ret == 2); // WAS 2
699 TEST_CHECK(talloc_reference_count(str) == 1); // NOW 1
700
701 ret = talloc_decrease_ref_count(str);
702 TEST_CHECK(ret == 1); // WAS 1, now 0 and freed
703
704 ret = talloc_total_blocks(ctx);
705 TEST_CHECK(ret == 1); // just ctx itself
706
707 ret = talloc_free(ctx);
708 TEST_CHECK(ret == 0);
709}
710
711/*
712 * === FreeRADIUS extension tests ===
713 */
714
715/*
716 * talloc_typed_strdup - should duplicate string and set type to char
717 */
719{
720 TALLOC_CTX *ctx;
721 char *dup;
722
723 ctx = talloc_init_const("test");
724
725 TEST_CASE("Duplicate a simple string");
726 dup = talloc_typed_strdup(ctx, "hello");
727 TEST_ASSERT(dup != NULL);
728 TEST_CHECK(strcmp(dup, "hello") == 0);
729 TEST_CHECK(talloc_get_size(dup) == 6);
730 TEST_CHECK(talloc_parent(dup) == ctx);
731
732 TEST_CASE("Duplicate an empty string");
733 dup = talloc_typed_strdup(ctx, "");
734 TEST_ASSERT(dup != NULL);
735 TEST_CHECK(dup[0] == '\0');
736 TEST_CHECK(talloc_get_size(dup) == 1);
737
738 TEST_CASE("Duplicate NULL returns NULL");
739 dup = talloc_typed_strdup(ctx, NULL);
740 TEST_CHECK(dup == NULL);
741
742 talloc_free(ctx);
743}
744
745/*
746 * talloc_typed_strndup - length-limited duplication
747 */
749{
750 TALLOC_CTX *ctx;
751 char *dup;
752
753 ctx = talloc_init_const("test");
754
755 TEST_CASE("Duplicate partial string");
756 dup = talloc_typed_strndup(ctx, "hello world", 5);
757 TEST_ASSERT(dup != NULL);
758 TEST_CHECK(strcmp(dup, "hello") == 0);
759 TEST_CHECK(talloc_get_size(dup) == 6);
760
761 TEST_CASE("Duplicate zero length");
762 dup = talloc_typed_strndup(ctx, "hello", 0);
763 TEST_ASSERT(dup != NULL);
764 TEST_CHECK(dup[0] == '\0');
765
766 talloc_free(ctx);
767}
768
769/*
770 * talloc_typed_asprintf - formatted string with correct type
771 */
773{
774 TALLOC_CTX *ctx;
775 char *str;
776
777 ctx = talloc_init_const("test");
778
779 TEST_CASE("Simple format string");
780 str = talloc_typed_asprintf(ctx, "hello %s %d", "world", 42);
781 TEST_ASSERT(str != NULL);
782 TEST_CHECK(strcmp(str, "hello world 42") == 0);
783
784 TEST_CASE("Empty format string");
785 str = talloc_typed_asprintf(ctx, "%s", "");
786 TEST_ASSERT(str != NULL);
787 TEST_CHECK(str[0] == '\0');
788
789 talloc_free(ctx);
790}
791
792/*
793 * talloc_bstrndup - binary safe string duplication
794 */
795static void test_talloc_bstrndup(void)
796{
797 TALLOC_CTX *ctx;
798 char *dup;
799
800 ctx = talloc_init_const("test");
801
802 TEST_CASE("Duplicate string with embedded NUL");
803 dup = talloc_bstrndup(ctx, "hel\0lo", 6);
804 TEST_ASSERT(dup != NULL);
805 TEST_CHECK(memcmp(dup, "hel\0lo", 6) == 0);
806 TEST_CHECK(dup[6] == '\0'); /* Should be NUL terminated */
807 TEST_CHECK(talloc_array_length(dup) == 7);
808
809 TEST_CASE("Duplicate zero-length string");
810 dup = talloc_bstrndup(ctx, "", 0);
811 TEST_ASSERT(dup != NULL);
812 TEST_CHECK(dup[0] == '\0');
813 TEST_CHECK(talloc_array_length(dup) == 1);
814
815 talloc_free(ctx);
816}
817
818/*
819 * talloc_bstr_append - append binary-safe strings
820 */
821static void test_talloc_bstr_append(void)
822{
823 TALLOC_CTX *ctx;
824 char *str, *result;
825
826 ctx = talloc_init_const("test");
827
828 TEST_CASE("Append to existing string");
829 str = talloc_bstrndup(ctx, "hello", 5);
830 result = talloc_bstr_append(ctx, str, " world", 6);
831 TEST_ASSERT(result != NULL);
832 TEST_CHECK(strcmp(result, "hello world") == 0);
833
834 TEST_CASE("Append to NULL creates new string");
835 result = talloc_bstr_append(ctx, NULL, "new", 3);
836 TEST_ASSERT(result != NULL);
837 TEST_CHECK(strcmp(result, "new") == 0);
838
839 talloc_free(ctx);
840}
841
842/*
843 * talloc_bstr_realloc - reallocate a bstr to a new length
844 */
846{
847 TALLOC_CTX *ctx;
848 char *str, *result;
849
850 ctx = talloc_init_const("test");
851
852 TEST_CASE("Realloc NULL allocates new buffer");
853 result = talloc_bstr_realloc(ctx, NULL, 10);
854 TEST_ASSERT(result != NULL);
855 TEST_CHECK(result[0] == '\0');
856 TEST_CHECK(talloc_array_length(result) == 11);
857
858 TEST_CASE("Realloc existing buffer to smaller size");
859 str = talloc_bstrndup(ctx, "hello world", 11);
860 result = talloc_bstr_realloc(ctx, str, 5);
861 TEST_ASSERT(result != NULL);
862 TEST_CHECK(result[5] == '\0');
863 TEST_CHECK(talloc_array_length(result) == 6);
864
865 talloc_free(ctx);
866}
867
868/*
869 * talloc_memcmp_array - compare uint8_t arrays
870 */
872{
873 TALLOC_CTX *ctx;
874 uint8_t *a, *b;
875 uint8_t data3[] = {1, 2, 3};
876 uint8_t data4a[] = {1, 2, 3, 4};
877 uint8_t data4b[] = {1, 2, 4, 4};
878
879 ctx = talloc_init_const("test");
880
881 TEST_CASE("Equal arrays");
882 a = talloc_typed_memdup(ctx, data3, sizeof(data3));
883 b = talloc_typed_memdup(ctx, data3, sizeof(data3));
885
886 TEST_CASE("First array longer");
887 talloc_free(a);
888 a = talloc_typed_memdup(ctx, data4a, sizeof(data4a));
890
891 TEST_CASE("Second array longer");
893
894 TEST_CASE("Same length, different content");
895 talloc_free(b);
896 b = talloc_typed_memdup(ctx, data4b, sizeof(data4b));
897 TEST_CHECK(talloc_memcmp_array(a, b) < 0); /* 3 < 4 */
898
899 talloc_free(ctx);
900}
901
902/*
903 * talloc_memcmp_bstr - compare char arrays
904 */
905static void test_talloc_memcmp_bstr(void)
906{
907 TALLOC_CTX *ctx;
908 char *a, *b;
909
910 ctx = talloc_init_const("test");
911
912 TEST_CASE("Equal strings");
913 a = talloc_bstrndup(ctx, "abc", 3);
914 b = talloc_bstrndup(ctx, "abc", 3);
915 TEST_CHECK(talloc_memcmp_bstr(a, b) == 0);
916
917 TEST_CASE("Different lengths");
918 talloc_free(a);
919 a = talloc_bstrndup(ctx, "abcd", 4);
921
922 talloc_free(ctx);
923}
924
925/*
926 * talloc_typed_memdup - duplicate uint8_t buffer
927 */
929{
930 TALLOC_CTX *ctx;
931 uint8_t data[] = {0xde, 0xad, 0xbe, 0xef};
932 uint8_t *dup;
933
934 ctx = talloc_init_const("test");
935
936 TEST_CASE("Duplicate binary data");
937 dup = talloc_typed_memdup(ctx, data, sizeof(data));
938 TEST_ASSERT(dup != NULL);
939 TEST_CHECK(memcmp(dup, data, sizeof(data)) == 0);
940 TEST_CHECK(talloc_get_size(dup) == sizeof(data));
941 TEST_CHECK(talloc_parent(dup) == ctx);
942
943 talloc_free(ctx);
944}
945
946/*
947 * talloc_buffer_append_buffer - concatenate talloc strings
948 */
950{
951 TALLOC_CTX *ctx;
952 char *a, *result;
953
954 ctx = talloc_init_const("test");
955
956 TEST_CASE("Concatenate two talloc strings");
957 a = talloc_strdup(ctx, "hello ");
958 {
959 char *b = talloc_strdup(ctx, "world");
960 result = talloc_buffer_append_buffer(ctx, a, b);
961 TEST_ASSERT(result != NULL);
962 TEST_CHECK(strcmp(result, "hello world") == 0);
963 talloc_free(b);
964 }
965
966 TEST_CASE("NULL first arg returns NULL");
967 {
968 char *b = talloc_strdup(ctx, "test");
969 result = talloc_buffer_append_buffer(ctx, NULL, b);
970 TEST_CHECK(result == NULL);
971 talloc_free(b);
972 }
973
974 TEST_CASE("NULL second arg returns NULL");
975 a = talloc_strdup(ctx, "hello");
976 result = talloc_buffer_append_buffer(ctx, a, NULL);
977 TEST_CHECK(result == NULL);
978
979 talloc_free(ctx);
980}
981
982/*
983 * talloc_array_null_terminate / talloc_array_null_strip
984 */
986{
987 TALLOC_CTX *ctx;
988 void **array, **result;
989
990 ctx = talloc_init_const("test");
991
992 TEST_CASE("NULL terminate an array");
993 array = talloc_array(ctx, void *, 3);
994 array[0] = (void *)1;
995 array[1] = (void *)2;
996 array[2] = (void *)3;
997 result = talloc_array_null_terminate(array);
998 TEST_ASSERT(result != NULL);
999 TEST_CHECK(talloc_array_length(result) == 4);
1000 TEST_CHECK(result[3] == NULL);
1001 TEST_CHECK(result[0] == (void *)1);
1002
1003 TEST_CASE("Strip NULL termination");
1004 result = talloc_array_null_strip(result);
1005 TEST_ASSERT(result != NULL);
1006 TEST_CHECK(talloc_array_length(result) == 3);
1007
1008 TEST_CASE("NULL terminate NULL returns NULL");
1010
1011 TEST_CASE("NULL strip NULL returns NULL");
1012 TEST_CHECK(talloc_array_null_strip(NULL) == NULL);
1013
1014 talloc_free(ctx);
1015}
1016
1017/*
1018 * talloc_destructor_add / talloc_destructor_disarm
1019 */
1021static void const *fr_destructor_uctx;
1022
1023static int test_fr_destructor_func(UNUSED void *fire_ctx, void *uctx)
1024{
1026 fr_destructor_uctx = uctx;
1027 return 0;
1028}
1029
1031{
1032 TALLOC_CTX *ctx, *fire;
1034
1035 ctx = talloc_init_const("test");
1036
1037 TEST_CASE("Destructor fires when fire_ctx is freed");
1039 fire = talloc(ctx, int);
1040 d = talloc_destructor_add(fire, NULL, test_fr_destructor_func, (void *)0x42);
1041 TEST_CHECK(d != NULL);
1042 talloc_free(fire);
1044 TEST_CHECK(fr_destructor_uctx == (void *)0x42);
1045
1046 TEST_CASE("Manual disarm via talloc_destructor_disarm");
1048 fire = talloc(ctx, int);
1049 d = talloc_destructor_add(fire, NULL, test_fr_destructor_func, NULL);
1050 TEST_ASSERT(d != NULL);
1052 talloc_free(fire);
1054
1055 TEST_CASE("NULL fire_ctx returns NULL");
1056 d = talloc_destructor_add(NULL, NULL, test_fr_destructor_func, NULL);
1057 TEST_CHECK(d == NULL);
1058
1059 talloc_free(ctx);
1060}
1061
1062/*
1063 * talloc_link_ctx - link parent and child lifetimes
1064 */
1065static void test_talloc_link_ctx(void)
1066{
1067 TALLOC_CTX *parent, *child;
1068 int ret;
1069
1070 TEST_CASE("Child freed when parent freed");
1071 parent = talloc_init_const("parent");
1072 child = talloc_init_const("child");
1073 ret = talloc_link_ctx(parent, child);
1074 TEST_CHECK(ret == 0);
1076}
1077
1078/*
1079 * talloc_hdr_size - calculate talloc chunk header size
1080 */
1081static void test_talloc_hdr_size(void)
1082{
1083 ssize_t hdr;
1084
1085 TEST_CASE("Header size is positive and reasonable");
1086 hdr = talloc_hdr_size();
1087 TEST_CHECK(hdr > 0);
1088 TEST_CHECK(hdr < 1024);
1089 TEST_CHECK(hdr > (ssize_t)sizeof(void *));
1090
1091 TEST_CASE("Repeated calls return same value");
1092 TEST_CHECK(talloc_hdr_size() == hdr);
1093}
1094
1095/*
1096 * talloc_child_ctx - ordered allocation and deallocation
1097 */
1098static int child_free_order[4];
1100
1101static int _track_free_order(int *ptr)
1102{
1103 int val = *ptr;
1105 return 0;
1106}
1107
1108static void test_talloc_child_ctx(void)
1109{
1110 TALLOC_CTX *ctx;
1111 TALLOC_CHILD_CTX *list, *c1, *c2, *c3;
1112 int *v1, *v2, *v3;
1113
1114 ctx = talloc_init_const("test");
1115
1116 TEST_CASE("Child ctx init");
1117 list = talloc_child_ctx_init(ctx);
1118 TEST_ASSERT(list != NULL);
1119
1120 TEST_CASE("Allocate children in order");
1121 c1 = talloc_child_ctx_alloc(list);
1122 TEST_ASSERT(c1 != NULL);
1123 v1 = talloc(c1, int);
1124 *v1 = 1;
1125 talloc_set_destructor(v1, _track_free_order);
1126
1127 c2 = talloc_child_ctx_alloc(list);
1128 TEST_ASSERT(c2 != NULL);
1129 v2 = talloc(c2, int);
1130 *v2 = 2;
1131 talloc_set_destructor(v2, _track_free_order);
1132
1133 c3 = talloc_child_ctx_alloc(list);
1134 TEST_ASSERT(c3 != NULL);
1135 v3 = talloc(c3, int);
1136 *v3 = 3;
1137 talloc_set_destructor(v3, _track_free_order);
1138
1139 TEST_CASE("Children freed in FILO order");
1140 child_free_idx = 0;
1141 memset(child_free_order, 0, sizeof(child_free_order));
1142 talloc_free(ctx);
1143
1144 /* FILO: c3 (newest) freed first, then c2, then c1 */
1148}
1149
1150/*
1151 * talloc_realloc_zero - realloc that zeros new memory
1152 */
1154{
1155 TALLOC_CTX *ctx;
1156 uint8_t *arr;
1157 unsigned int i;
1158
1159 ctx = talloc_init_const("test");
1160
1161 TEST_CASE("Initial allocation");
1162 arr = talloc_array(ctx, uint8_t, 4);
1163 TEST_ASSERT(arr != NULL);
1164 memset(arr, 0xff, 4);
1165
1166 TEST_CASE("Realloc larger zeros new portion");
1167 arr = talloc_realloc_zero(ctx, arr, uint8_t, 16);
1168 TEST_ASSERT(arr != NULL);
1169
1170 /* Original bytes preserved */
1171 for (i = 0; i < 4; i++) {
1172 TEST_CHECK(arr[i] == 0xff);
1173 }
1174
1175 /* New bytes zeroed */
1176 for (i = 4; i < 16; i++) {
1177 TEST_CHECK(arr[i] == 0);
1178 }
1179
1180 talloc_free(ctx);
1181}
1182
1183/*
1184 * talloc_decrease_ref_count
1185 */
1187{
1188 TALLOC_CTX *ctx, *ref_ctx;
1189 char *str;
1190 int ret;
1191
1192 ctx = talloc_init_const("test");
1193 ref_ctx = talloc_init_const("ref");
1194
1195 TEST_CASE("Decrease ref count with no references frees memory");
1196 str = talloc_strdup(ctx, "test");
1197 ret = talloc_decrease_ref_count(str);
1198 TEST_CHECK(ret == 0);
1199
1200 TEST_CASE("NULL ptr returns 0");
1201 ret = talloc_decrease_ref_count(NULL);
1202 TEST_CHECK(ret == 0);
1203
1204 TEST_CASE("With a reference, unlinks instead of freeing");
1205 str = talloc_strdup(ctx, "referenced");
1206 talloc_reference(ref_ctx, str);
1207 ret = talloc_decrease_ref_count(str);
1208 TEST_CHECK(ret == 1); /* One reference remains */
1209
1210 talloc_free(ctx);
1211 talloc_free(ref_ctx);
1212}
1213
1214/*
1215 * talloc_aligned_array - page-aligned allocation
1216 */
1218{
1219 TALLOC_CTX *ctx, *array;
1220 void *start;
1221 size_t page_size = (size_t)getpagesize();
1222
1223 ctx = talloc_init_const("test");
1224
1225 TEST_CASE("Aligned array returns non-NULL");
1226 array = talloc_aligned_array(ctx, &start, page_size, page_size);
1227 TEST_CHECK(array != NULL);
1228 TEST_CHECK(start != NULL);
1229
1230 TEST_CASE("Start address is page-aligned");
1231 TEST_CHECK(((uintptr_t)start % page_size) == 0);
1232
1233 talloc_free(ctx);
1234}
1235
1237 /* Core talloc (samba) tests */
1238 { "talloc_basic", test_talloc_basic },
1239 { "talloc_zero", test_talloc_zero },
1240 { "talloc_array", test_talloc_array },
1241 { "talloc_free", test_talloc_free },
1242 { "talloc_naming", test_talloc_naming },
1243 { "talloc_parent", test_talloc_parent },
1244 { "talloc_steal", test_talloc_steal },
1245 { "talloc_move", test_talloc_move },
1246 { "talloc_reference", test_talloc_reference },
1247 { "talloc_set_destructor", test_talloc_set_destructor },
1248 { "talloc_strdup", test_talloc_strdup },
1249 { "talloc_asprintf", test_talloc_asprintf },
1250 { "talloc_pool", test_talloc_pool },
1251 { "talloc_free_children", test_talloc_free_children },
1252 { "talloc_total_size", test_talloc_total_size },
1253 { "talloc_get_size", test_talloc_get_size },
1254 { "talloc_find_parent_byname", test_talloc_find_parent_byname },
1255 { "talloc_is_parent", test_talloc_is_parent },
1256 { "talloc_reparent", test_talloc_reparent },
1257 { "talloc_memdup", test_talloc_memdup },
1258 { "talloc_deep_hierarchy", test_talloc_deep_hierarchy },
1259 { "talloc_strndup_append", test_talloc_strndup_append },
1260 { "talloc_increase_ref_count", test_talloc_increase_ref_count },
1261
1262 /* FreeRADIUS extension tests */
1263 { "talloc_typed_strdup", test_talloc_typed_strdup },
1264 { "talloc_typed_strndup", test_talloc_typed_strndup },
1265 { "talloc_typed_asprintf", test_talloc_typed_asprintf },
1266 { "talloc_bstrndup", test_talloc_bstrndup },
1267 { "talloc_bstr_append", test_talloc_bstr_append },
1268 { "talloc_bstr_realloc", test_talloc_bstr_realloc },
1269 { "talloc_memcmp_array", test_talloc_memcmp_array },
1270 { "talloc_memcmp_bstr", test_talloc_memcmp_bstr },
1271 { "talloc_typed_memdup", test_talloc_typed_memdup },
1272 { "talloc_buffer_append_buffer", test_talloc_buffer_append_buffer },
1273 { "talloc_array_null_terminate", test_talloc_array_null_terminate },
1274 { "talloc_destructor_add", test_talloc_destructor_add },
1275 { "talloc_link_ctx", test_talloc_link_ctx },
1276 { "talloc_hdr_size", test_talloc_hdr_size },
1277 { "talloc_child_ctx", test_talloc_child_ctx },
1278 { "talloc_realloc_zero", test_talloc_realloc_zero },
1279 { "talloc_decrease_ref_count", test_talloc_decrease_ref_count },
1280 { "talloc_aligned_array", test_talloc_aligned_array },
1281
1283};
#define TEST_CHECK(cond)
Definition acutest.h:87
#define TEST_CASE(name)
Definition acutest.h:186
#define TEST_ASSERT(cond)
Definition acutest.h:110
#define TEST_TERMINATOR
Definition acutest.h:64
#define UNUSED
Definition build.h:336
talloc_free(hp)
long int ssize_t
unsigned char uint8_t
unsigned long int size_t
void ** talloc_array_null_terminate(void **array)
Add a NULL pointer to an array of pointers.
Definition talloc.c:907
TALLOC_CHILD_CTX * talloc_child_ctx_alloc(TALLOC_CHILD_CTX *parent)
Allocate a TALLOC_CHILD_CTX from a parent.
Definition talloc.c:1074
fr_talloc_destructor_t * talloc_destructor_add(TALLOC_CTX *fire_ctx, TALLOC_CTX *disarm_ctx, fr_talloc_free_func_t func, void const *uctx)
Add an additional destructor to a talloc chunk.
Definition talloc.c:96
ssize_t talloc_hdr_size(void)
Calculate the size of the talloc chunk header.
Definition talloc.c:271
TALLOC_CHILD_CTX * talloc_child_ctx_init(TALLOC_CTX *ctx)
Allocate and initialize a TALLOC_CHILD_CTX.
Definition talloc.c:1060
int talloc_memcmp_array(uint8_t const *a, uint8_t const *b)
Compares two talloced uint8_t arrays with memcmp.
Definition talloc.c:826
char * talloc_bstr_realloc(TALLOC_CTX *ctx, char *in, size_t inlen)
Trim a bstr (char) buffer.
Definition talloc.c:681
char * talloc_typed_asprintf(TALLOC_CTX *ctx, char const *fmt,...)
Call talloc vasprintf, setting the type on the new chunk correctly.
Definition talloc.c:545
TALLOC_CTX * talloc_aligned_array(TALLOC_CTX *ctx, void **start, size_t alignment, size_t size)
Return a page aligned talloc memory array.
Definition talloc.c:196
int talloc_link_ctx(TALLOC_CTX *parent, TALLOC_CTX *child)
Link two different parent and child contexts, so the child is freed before the parent.
Definition talloc.c:167
uint8_t * talloc_typed_memdup(TALLOC_CTX *ctx, uint8_t const *in, size_t inlen)
Call talloc_memdup, setting the type on the new chunk correctly.
Definition talloc.c:445
char * talloc_bstrndup(TALLOC_CTX *ctx, char const *in, size_t inlen)
Binary safe strndup function.
Definition talloc.c:617
char * talloc_typed_strdup(TALLOC_CTX *ctx, char const *p)
Call talloc_strdup, setting the type on the new chunk correctly.
Definition talloc.c:470
int talloc_decrease_ref_count(void const *ptr)
Decrease the reference count on a ptr.
Definition talloc.c:874
char * talloc_typed_strndup(TALLOC_CTX *ctx, char const *p, size_t len)
Call talloc_strndup, setting the type on the new chunk correctly.
Definition talloc.c:521
char * talloc_buffer_append_buffer(TALLOC_CTX *ctx, char *to, char const *from)
Concatenate to + from.
Definition talloc.c:714
void ** talloc_array_null_strip(void **array)
Remove a NULL termination pointer from an array of pointers.
Definition talloc.c:937
char * talloc_bstr_append(TALLOC_CTX *ctx, char *to, char const *from, size_t from_len)
Append a bstr to a bstr.
Definition talloc.c:645
void talloc_destructor_disarm(fr_talloc_destructor_t *d)
Disarm a destructor and free all memory allocated in the trigger ctxs.
Definition talloc.c:138
int talloc_memcmp_bstr(char const *a, char const *b)
Compares two talloced char arrays with memcmp.
Definition talloc.c:850
#define talloc_strndup(_ctx, _str, _len)
Definition talloc.h:143
static TALLOC_CTX * talloc_init_const(char const *name)
Allocate a top level chunk with a constant name.
Definition talloc.h:120
#define talloc_asprintf
Definition talloc.h:144
#define talloc_strdup(_ctx, _str)
Definition talloc.h:142
#define talloc_realloc_zero(_ctx, _ptr, _type, _count)
Definition talloc.h:211
Structure to record a destructor operation on a specific talloc chunk.
Definition talloc.h:86
static int native_destructor_count
static void test_talloc_bstrndup(void)
static void test_talloc_steal(void)
static void test_talloc_buffer_append_buffer(void)
TEST_LIST
static void test_talloc_free_children(void)
static int _track_free_order(int *ptr)
static void test_talloc_get_size(void)
static int test_fr_destructor_func(UNUSED void *fire_ctx, void *uctx)
static int native_destructor(int *ptr)
static void test_talloc_decrease_ref_count(void)
static void test_talloc_hdr_size(void)
static void test_talloc_zero(void)
static void test_talloc_typed_memdup(void)
static void test_talloc_is_parent(void)
static int child_free_idx
static void test_talloc_move(void)
static void test_talloc_parent(void)
static void test_talloc_typed_strndup(void)
static void const * fr_destructor_uctx
static void test_talloc_destructor_add(void)
static void test_talloc_bstr_append(void)
static void test_talloc_reparent(void)
static void test_talloc_deep_hierarchy(void)
static void test_talloc_asprintf(void)
static void test_talloc_reference(void)
static void test_talloc_typed_asprintf(void)
static void test_talloc_naming(void)
static void test_talloc_memcmp_array(void)
static void test_talloc_find_parent_byname(void)
static void test_talloc_typed_strdup(void)
static void test_talloc_basic(void)
static void test_talloc_link_ctx(void)
static void test_talloc_child_ctx(void)
static void test_talloc_aligned_array(void)
static void test_talloc_free(void)
static void test_talloc_array(void)
static void test_talloc_strdup(void)
static void test_talloc_set_destructor(void)
static void test_talloc_array_null_terminate(void)
static void test_talloc_increase_ref_count(void)
static void test_talloc_strndup_append(void)
static void test_talloc_bstr_realloc(void)
static int fr_destructor_called
static void test_talloc_realloc_zero(void)
static void test_talloc_memcmp_bstr(void)
static void test_talloc_pool(void)
static int child_free_order[4]
static void test_talloc_memdup(void)
static void test_talloc_total_size(void)
static fr_slen_t parent
Definition pair.h:858
static fr_slen_t data
Definition value.h:1340