The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
pair_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 a AVP manipulation and search API.
18 *
19 * @file src/lib/util/test//pair_tests.c
20 * @author Jorge Pereira <jpereira@freeradius.org>
21 * @copyright 2020 Network RADIUS SAS (legal@networkradius.com)
22 */
23
24/**
25 * The 'TEST_INIT' macro provided by 'acutest.h' allowing to register a function to be called
26 * before call the unit tests. Therefore, It calls the function ALL THE TIME causing an overhead.
27 * That is why we are initializing test_init() by "__attribute__((constructor));" reducing the
28 * test execution by 50% of the time.
29 */
30#define USE_CONSTRUCTOR
31
32/*
33 * It should be declared before include the "acutest.h"
34 */
35#ifdef USE_CONSTRUCTOR
36static void test_init(void) __attribute__((constructor));
37#else
38static void test_init(void);
39# define TEST_INIT test_init()
40#endif
41
42#include "acutest_common_init.h"
43#include "acutest_helpers.h"
44#include "pair_test_helpers.h"
45
46#include <freeradius-devel/util/conf.h>
47#include <freeradius-devel/util/dict.h>
48#include <freeradius-devel/util/sbuff.h>
49
50static TALLOC_CTX *autofree;
52static fr_dict_t *test_dict;
53
54/** Global initialisation
55 */
56static void test_init(void)
57{
59 if (!autofree) {
60 error:
61#ifdef TEST_NESTED_PAIRS
62 fr_perror("pair_nested_tests");
63#else
64 fr_perror("pair_tests");
65#endif
66 fr_exit_now(EXIT_FAILURE);
67 }
68
69 /*
70 * Mismatch between the binary and the libraries it depends on
71 */
72 if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) goto error;
73
74 if (fr_dict_test_init(autofree, &test_dict, NULL) < 0) goto error;
75
76 /* Initialize the "test_pairs" list */
78
79#ifdef TEST_NESTED_PAIRS
80 if (fr_pair_test_list_alloc_nested(autofree, &test_pairs, NULL) < 0) goto error;
81#else
82 if (fr_pair_test_list_alloc(autofree, &test_pairs, NULL) < 0) goto error;
83#endif
84}
85
86/*
87 * Tests functions
88 */
89static void test_fr_pair_afrom_da(void)
90{
92
93 TEST_CASE("Allocation using fr_pair_afrom_da");
95
96 TEST_CHECK(vp != NULL);
97 if (!vp) return;
98
100
101 TEST_CASE("Validating PAIR_VERIFY()");
103
104 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
105 TEST_MSG("Expected vp->vp_strvalue == test_string");
106
108}
109
111{
112 fr_pair_t *vp;
113 unsigned int attr = FR_TEST_ATTR_STRING;
114
115 TEST_CASE("Allocation using fr_pair_afrom_child_num");
117
118 TEST_CASE("Validating PAIR_VERIFY()");
120
121 TEST_CHECK(vp && vp->da->attr == FR_TEST_ATTR_STRING);
122 TEST_MSG("Expected attr(%u) == vp->da->attr(%u)", attr, vp->da->attr);
123
125}
126
128{
129 fr_pair_t *vp, *parent = NULL;
131
133
134 TEST_CASE("Allocation using fr_pair_afrom_da_nested");
136
138 TEST_MSG("Expected attr(%s) == vp->da->attr(%s)", fr_dict_attr_test_tlv_string->name, vp->da->name);
139
140 TEST_CASE("Validating PAIR_VERIFY()");
142
143 TEST_CASE("Top list does not have the tlv child attribute");
145
146 TEST_CASE("Top list does have the tlv attribute");
148 TEST_ASSERT(parent != NULL);
149
150 TEST_CASE("Parent list does have the tlv child attribute");
152
153 talloc_free(parent); /* not vp! */
154}
155
157{
158 int count;
159 fr_pair_t *vp, *parent = NULL;
161
163
164 TEST_CASE("Allocation using fr_pair_afrom_da_nested");
166
168 TEST_MSG("Expected attr(%s) == vp->da->attr(%s)", fr_dict_attr_test_tlv_string->name, vp->da->name);
169
170 TEST_CASE("Deleted nested pair");
172
173 TEST_CASE("Top list still has the tlv attribute");
175 TEST_ASSERT(parent != NULL);
176
177 TEST_CASE("Parent list does not have the tlv child attribute");
179
181}
182
188
189
190static void test_fr_pair_copy(void)
191{
192 fr_pair_t *vp, *copy;
193
194 TEST_CASE("Allocation using fr_pair_copy");
196
197 TEST_CASE("Validating PAIR_VERIFY()");
199
200 copy = fr_pair_copy(autofree, vp);
201
202 TEST_CASE("Validating PAIR_VERIFY()");
203 PAIR_VERIFY(copy);
204
205 vp->op = T_OP_CMP_EQ;
206
207 TEST_CASE("Compare fr_pair_cmp(copy == vp) should be TRUE");
208 TEST_CHECK(fr_pair_cmp(vp, copy) == 1);
209
211 talloc_free(copy);
212}
213
214static void test_fr_pair_steal(void)
215{
216 fr_pair_t *vp;
217 TALLOC_CTX *ctx = talloc_null_ctx();
218
219 TEST_CASE("Allocate a new attribute fr_pair_afrom_da");
221
222 TEST_CASE("Validating PAIR_VERIFY()");
224
225 TEST_CASE("Stealing 'vp' pair using fr_pair_steal()");
226 fr_pair_steal(autofree, vp); /* It should exit without memory-leaks */
227
228 TEST_CASE("Checking if talloc_parent(vp) == autofree");
229 TEST_CHECK(talloc_parent(vp) == autofree);
230}
231
233{
234 fr_pair_t *vp;
235 uint8_t value = 0;
236
237 TEST_CASE("Allocate a new attribute fr_pair_afrom_da");
239
240 TEST_CASE("Validating PAIR_VERIFY()");
242
243 TEST_CASE("Converting regular 'vp' as unknown");
245
246 TEST_CASE("Checking if a real 'raw' vp");
247 TEST_CHECK(vp && vp->vp_raw);
248}
249
251{
252 fr_pair_t *vp, *needle;
253 fr_dcursor_t cursor;
254
255 TEST_CASE("Searching for fr_dict_attr_test_uint32 using fr_pair_dcursor_by_da_init()");
256 needle = NULL;
258 vp;
259 vp = fr_dcursor_next(&cursor)) {
260 if (!needle) {
261 needle = vp;
262 continue;
263 }
264 TEST_CHECK(1 == 1); /* this never will be reached */
265 }
266
267 TEST_CASE("Validating PAIR_VERIFY()");
268
269 TEST_CHECK(needle != NULL);
270 if (needle) PAIR_VERIFY(needle);
271
272 TEST_CASE("Expected (needle->da == fr_dict_attr_test_uint32)");
273 TEST_CHECK(needle && needle->da == fr_dict_attr_test_uint32);
274}
275
277{
278 fr_pair_t *vp, *needle;
279 fr_dcursor_t cursor;
280
281 TEST_CASE("Searching for fr_dict_attr_test_tlv_string as ascend of fr_dict_attr_test_tlv using fr_pair_dcursor_by_ancestor_init()");
282 needle = NULL;
284 vp;
285 vp = fr_dcursor_next(&cursor)) {
286 TEST_CHECK(vp != NULL);
288 needle = vp;
289 continue;
290 }
291 }
292
293 TEST_CHECK(needle != NULL);
294
295 TEST_CASE("Validating PAIR_VERIFY()");
296 if (needle) PAIR_VERIFY(needle);
297
298 TEST_CASE("Expected (needle->da == fr_dict_attr_test_tlv_string)");
299 TEST_CHECK(needle && needle->da == fr_dict_attr_test_tlv_string);
300}
301
303{
304 int i = 0;
305 fr_value_box_t *box;
306 fr_dcursor_t cursor;
307 fr_pair_t *vp;
309
311
313 fr_pair_value_strdup(vp, "hello", false);
315
317 vp->vp_uint32 = 6809;
319
321 vp->vp_uint8 = 12;
323
324 TEST_CASE("Searching for fr_dict_attr_test_tlv_string as ascend of fr_dict_attr_test_tlv using fr_pair_dcursor_by_ancestor_init()");
325 for (box = fr_pair_dcursor_value_init(&cursor);
326 box;
327 box = fr_dcursor_next(&cursor), i++) {
328 switch (i) {
329 case 0:
330 TEST_CASE("First box is a string with value 'hello'");
331 TEST_CHECK(box->type == FR_TYPE_STRING);
332 TEST_CHECK(strcmp(box->vb_strvalue, "hello") == 0);
333 break;
334
335 case 1:
336 TEST_CASE("First box is a uint32 with value 6809");
337 TEST_CHECK(box->type == FR_TYPE_UINT32);
338 TEST_CHECK(box->vb_uint32 == 6809);
339 break;
340
341 case 2:
342 TEST_CASE("First box is a uint8 r with value 12");
343 TEST_CHECK(box->type == FR_TYPE_UINT8);
344 TEST_CHECK(box->vb_uint8 == 12);
345 break;
346
347 default:
348 TEST_CASE("Too many pairs");
349 TEST_CHECK(i < 3);
350 break;
351 }
352 }
353
355}
356
358{
359 fr_pair_t *vp;
360
361 TEST_CASE("Search for fr_dict_attr_test_string using fr_pair_find_by_da_idx()");
363
364 TEST_CASE("Validating PAIR_VERIFY()");
366
367 TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
369}
370
372{
373 fr_pair_t *vp;
374
375 TEST_CASE("Search for FR_TEST_ATTR_STRING using fr_pair_find_by_child_num_idx()");
377
378 TEST_CASE("Validating PAIR_VERIFY()");
380
381 TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
383}
384
386{
387 fr_pair_t *vp1, *vp2, *vp3, *vp4, *vp5, *vp_found;
389
391
392 /*
393 * Build a list with 2 TLV structures, each with different leaf nodes
394 */
398 fr_pair_append(&vp1->vp_group, vp2);
400 fr_pair_append(&vp2->vp_group, vp1);
404 fr_pair_append(&vp2->vp_group, vp3);
406 fr_pair_append(&vp3->vp_group, vp2);
407
409 TEST_CASE("Find child node in first TLV");
410 TEST_CHECK_PAIR(vp_found, vp1);
411
413 TEST_CASE("Find child node in second TLV");
414 TEST_CHECK_PAIR(vp_found, vp2);
415
416 /*
417 * Add third nested TLV with child of same type as first
418 */
422 fr_pair_append(&vp3->vp_group, vp4);
424 fr_pair_append(&vp4->vp_group, vp3);
425
426 /*
427 * A second attribute of the same type further down the list does
428 * not change which one is found.
429 */
431 TEST_CASE("Find child node in first TLV");
432 TEST_CHECK_PAIR(vp_found, vp1);
433
434 /*
435 * Add some "flat list" attributes
436 */
441
442 /*
443 * The search looks in the nesting before it looks at the flat
444 * list, so the nested attribute wins even though vp4 was
445 * prepended, and therefore comes first in the top level list.
446 */
448 TEST_CASE("A nested attribute is found before a flat one");
449 TEST_CHECK_PAIR(vp_found, vp1);
450
452
453 /*
454 * With no nesting to search, the flat attribute is the answer.
455 * This is the fallback at the end of fr_pair_find_by_da_nested().
456 */
458
461
463 TEST_CASE("Find a flat attribute when there is no nesting");
464 TEST_CHECK_PAIR(vp_found, vp5);
465
466 TEST_CASE("Find nothing when the attribute is not there at all");
468
470}
471
472static void test_fr_pair_append(void)
473{
474 fr_pair_t *vp;
476 size_t count = 0;
477
478 TEST_CASE("Add 3 pairs using fr_pair_append()");
479
481
488
489 /* lets' count */
491
492 TEST_CASE("Expected (count == 3)");
493 TEST_CHECK(count == 3);
494
496}
497
499{
500 fr_pair_t *leaf1, *leaf2, *found, *inter1, *inter2;
502 int ret;
503
505
506 TEST_CASE("Add nested attribute including parents");
508 TEST_CHECK(ret == 0);
509 TEST_CHECK(leaf1 != NULL);
510
511 TEST_CASE("Check nested attributes added");
513 TEST_ASSERT(found != NULL);
514 inter1 = found;
515 found = fr_pair_find_by_da(&inter1->vp_group, NULL, fr_dict_attr_test_nested_child_tlv);
516 TEST_ASSERT(found != NULL);
517 inter2 = found;
518 found = fr_pair_find_by_da(&inter2->vp_group, NULL, fr_dict_attr_test_nested_leaf_int32);
519 TEST_CHECK_PAIR(found, leaf1);
520
521 TEST_CASE("Ensure no flat list attribute created");
523 TEST_CHECK_PAIR(found, NULL);
524
525 TEST_CASE("Add additional nested attribute where parents exist");
527 TEST_CHECK(ret == 0);
528 TEST_CHECK(leaf2 != NULL);
529 TEST_CHECK(leaf2 != leaf1);
530
531 TEST_CASE("Check additional leaf added under existing parent");
532 found = fr_pair_find_by_da(&inter2->vp_group, NULL, fr_dict_attr_test_nested_leaf_string);
533 TEST_CHECK_PAIR(found, leaf2);
534
535 TEST_CASE("Check no extra parent attributes created");
537 TEST_CHECK_PAIR(found, inter1);
539 TEST_CHECK_PAIR(found, NULL);
540
541 found = fr_pair_find_by_da(&inter1->vp_group, NULL, fr_dict_attr_test_nested_child_tlv);
542 TEST_CHECK_PAIR(found, inter2);
543 found = fr_pair_find_by_da(&inter1->vp_group, inter2, fr_dict_attr_test_nested_child_tlv);
544 TEST_CHECK_PAIR(found, NULL);
545
547}
548
550{
551 TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete_by_child_num()");
553
554 TEST_CASE("The fr_dict_attr_test_string shouldn't exist in 'test_pairs'");
556
557 TEST_CASE("Add fr_dict_attr_test_string back into 'test_pairs'");
559}
560
562{
564 TALLOC_CTX *ctx = talloc_null_ctx();
565
567
568 TEST_CASE("Add using fr_pair_prepend_by_da()");
570
571 /* lets' count */
573 TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
575 }
576
578}
579
581{
582 fr_pair_t *vp, *group;
583
585 if (!group) return; /* quiet clang scan */
586
587 TEST_CASE("Update Add using fr_pair_prepend_by_da()");
588 TEST_CHECK(fr_pair_update_by_da_parent(group, &vp, fr_dict_attr_test_uint32) == 0); /* attribute doesn't exist in this group */
589 vp->vp_uint32 = 54321;
590
591 TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 54321)");
592 TEST_CHECK((vp = fr_pair_find_by_da(&group->vp_group, NULL, fr_dict_attr_test_uint32)) != NULL);
593
594 TEST_CASE("Validating PAIR_VERIFY()");
596
597 TEST_CASE("Expected (vp == 54321)");
598 TEST_CHECK(vp && vp->vp_uint32 == 54321);
599
600 talloc_free(group);
601}
602
604{
605 TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete_by_da()");
607
608 TEST_CASE("The fr_dict_attr_test_string shouldn't exist in 'test_pairs'");
610
611 TEST_CASE("Add fr_dict_attr_test_string back into 'test_pairs'");
613}
614
615static void test_fr_pair_delete(void)
616{
617 fr_pair_t *vp;
618
619 TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete()");
622
623 TEST_CASE("The fr_dict_attr_test_string shouldn't exist in 'test_pairs'");
625
626 TEST_CASE("Add fr_dict_attr_test_string back into 'test_pairs'");
628}
629
630static void test_fr_pair_cmp(void)
631{
632 fr_pair_t *vp1, *vp2;
633
634 TEST_CASE("Create the vp1 'Test-Integer = 123'");
636
637 TEST_CASE("Validating PAIR_VERIFY()");
638 PAIR_VERIFY(vp1);
639
640 vp1->op = T_OP_EQ;
641 vp1->vp_uint32 = 123;
642
643 TEST_CASE("Create the vp2 'Test-Integer = 321'");
645
646 TEST_CASE("Validating PAIR_VERIFY()");
647 PAIR_VERIFY(vp2);
648
649 vp2->op = T_OP_CMP_EQ;
650 vp2->vp_uint32 = 321;
651
652 TEST_CASE("Compare fr_pair_cmp(vp1 == vp2) should be FALSE");
653 TEST_CHECK(fr_pair_cmp(vp1, vp2) == 0);
654}
655
656static void test_fr_pair_list_cmp(void)
657{
658 fr_pair_list_t local_pairs1, local_pairs2;
659
660 fr_pair_list_init(&local_pairs1);
661 fr_pair_list_init(&local_pairs2);
662
663 TEST_CASE("Create 'local_pairs1'");
664 TEST_CHECK(fr_pair_test_list_alloc(autofree, &local_pairs1, NULL) == 0);
665
666 TEST_CASE("Create 'local_pairs2'");
667 TEST_CHECK(fr_pair_test_list_alloc(autofree, &local_pairs2, NULL) == 0);
668
669 TEST_CASE("Check if 'local_pairs1' == 'local_pairs2' using fr_pair_list_cmp()");
670 TEST_CHECK(fr_pair_list_cmp(&local_pairs1, &local_pairs2) == 0);
671
672 fr_pair_list_free(&local_pairs1);
673 fr_pair_list_free(&local_pairs2);
674}
675
676static void test_fr_pair_list_copy(void)
677{
679
681
682 TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
684
685 TEST_CASE("Check if 'local_pairs' == 'test_pairs' using fr_pair_list_cmp()");
687
689}
690
692{
694
696
697 TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
699
700 TEST_CASE("The 'local_pairs' should have only fr_dict_attr_test_string");
702 TEST_CASE("Validating PAIR_VERIFY()");
704
705 TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
707 }
708
710}
711
713{
714 fr_pair_t *vp;
716
718
719 TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
721
722 TEST_CASE("The 'local_pairs' should have only one attribute in it");
724
725 TEST_CASE("The 'local_pairs' should have only fr_dict_attr_test_tlv_string (ancestor of 'Test-TLV-Root'");
727
728 TEST_CASE("Validating we copied the attribute");
729 TEST_CHECK(vp != NULL);
730 if (!vp) return;
731
732#ifdef TEST_NESTED_PAIRS
733 TEST_CASE("Expected copied attribute == fr_dict_attr_test_tlv)");
735#else
736 TEST_CASE("Expected copied attribute == fr_dict_attr_test_tlv_string)");
738#endif
739
740 TEST_CASE("Verifying the copied attribute");
742
743 TEST_CASE("Expecting nothing else in local list");
745
747}
748
749static void test_fr_pair_list_sort(void)
750{
751 fr_dcursor_t cursor;
752 fr_pair_t *vp;
754 TALLOC_CTX *ctx = talloc_null_ctx();
755
756 TEST_CASE("Create 'local_pairs' with 3 attributes not ordered");
758
759 TEST_CASE("Add fr_dict_attr_test_string back into 'local_pairs'");
764 TEST_CHECK(fr_pair_prepend_by_da(ctx, NULL, &local_pairs, fr_dict_attr_test_enum) == 0); // It will be go to the tail
766
767 /*
768 * FIXME - This test doesn't check for intra-type stability
769 */
770 TEST_CASE("Sorting 'local_pairs' by fr_pair_list_sort(local_pairs, fr_pair_cmp_by_da)");
772
773 TEST_CASE("1st (da == fr_dict_attr_test_string)");
774 TEST_CHECK((vp = fr_pair_dcursor_init(&cursor, &local_pairs)) != NULL);
776
777 TEST_CASE("2nd (da == fr_dict_attr_test_octets)");
778 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
780
781 TEST_CASE("3rd (da == fr_dict_attr_test_ipv4_addr)");
782 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
784
785 TEST_CASE("4th (da == fr_dict_attr_test_uint32)");
786 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
788
789 TEST_CASE("5th (da == fr_dict_attr_test_date)");
790 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
792
793 TEST_CASE("6th (da == fr_dict_attr_test_enum)");
794 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
796
798}
799
800static void test_fr_pair_value_copy(void)
801{
802 fr_pair_t *vp1, *vp2;
803
804 TEST_CASE("Create 'vp1' with Test-Integer = 123");
806 vp1->vp_uint32 = 123;
807
808 TEST_CASE("Validating PAIR_VERIFY()");
809 PAIR_VERIFY(vp1);
810
811 TEST_CASE("Create 'vp2'");
813
814 TEST_CASE("Validating PAIR_VERIFY()");
815 PAIR_VERIFY(vp2);
816
817 TEST_CASE("Copy 'vp1' to 'vp2' using fr_pair_value_copy()");
818 TEST_CHECK(fr_pair_value_copy(vp2, vp1) == 0);
819
820 TEST_CASE("Validating PAIR_VERIFY()");
821 PAIR_VERIFY(vp2);
822
823 TEST_CASE("Check (vp1 == vp2)");
824 TEST_CHECK(vp2->vp_uint32 == 123);
825}
826
828{
829 fr_pair_t *vp;
830
831 TEST_CASE("Find 'Test-String'");
833
834 TEST_CASE("Validating PAIR_VERIFY()");
836
837 TEST_CASE("Convert 'test_string' value to attribute value using fr_pair_value_from_str()");
839
840 TEST_CASE("Validating PAIR_VERIFY()");
842
843 TEST_CASE("Check (vp->vp_string == test_string)");
844 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
845}
846
848{
849 fr_pair_t *vp;
850
851 TEST_CASE("Find 'Test-String'");
853
854 TEST_CASE("Validating PAIR_VERIFY()");
856
857 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup()");
859
860 TEST_CASE("Validating PAIR_VERIFY()");
862
863 TEST_CASE("Check (vp->vp_string == test_string)");
864 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
865}
866
868{
869 fr_pair_t *vp, *nvp;
870 char *copy_test_string;
871
872 TEST_CASE("Find 'Test-String'");
874
875 TEST_CASE("Validating PAIR_VERIFY()");
877
878 MEM(nvp = fr_pair_copy(NULL, vp));
879
880 copy_test_string = talloc_strdup(nvp, test_string);
881 talloc_set_type(copy_test_string, char);
882
883 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup_shallow()");
884 TEST_CHECK(fr_pair_value_strdup_shallow(nvp, copy_test_string, true) == 0);
885
886 TEST_CASE("Validating PAIR_VERIFY()");
887 PAIR_VERIFY(nvp);
888
889 TEST_CASE("Check (vp->vp_string == copy_test_string)");
890 TEST_CHECK(nvp && strncmp(nvp->vp_strvalue, test_string, strlen(copy_test_string)) == 0);
891
892 talloc_free(nvp);
893}
894
896{
897 fr_pair_t *vp;
898
899 TEST_CASE("Find 'Test-String'");
901
902 TEST_CASE("Validating PAIR_VERIFY()");
904
905 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup_shallow()");
907
908 TEST_CASE("Trim the length of the string buffer using fr_pair_value_strtrim()");
910
911 TEST_CASE("Validating PAIR_VERIFY()");
913
914 TEST_CASE("Check (vp->vp_string == test_string)");
915 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
916}
917
919{
920 fr_pair_t *vp;
921 char fmt_test[64];
922 fr_time_t now = fr_time();
923
924 snprintf(fmt_test, sizeof(fmt_test), "Now is %"PRId64, fr_time_unwrap(now));
925
926 TEST_CASE("Find 'Test-String'");
928
929 TEST_CASE("Validating PAIR_VERIFY()");
931
932 TEST_CASE("Copy content of 'fmt_test' to attribute value using fr_pair_value_aprintf()");
933 TEST_CHECK(fr_pair_value_aprintf(vp, "Now is %"PRId64, fr_time_unwrap(now)) == 0);
934
935 TEST_CASE("Validating PAIR_VERIFY()");
937
938 TEST_CASE("Check (vp->vp_string == fmt_test)");
939 TEST_CHECK(vp && strcmp(vp->vp_strvalue, fmt_test) == 0);
940}
941
943{
944 fr_pair_t *vp;
945 char *out = NULL;
946
947 TEST_CASE("Find 'Test-String'");
949
950 TEST_CASE("Validating PAIR_VERIFY()");
952
953 TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
955
956 TEST_CASE("Validating PAIR_VERIFY()");
958
959 TEST_CASE("Copy 'test_string' to the pre-allocated pointer");
961
962 TEST_CASE("Check (out == test_string)");
963 TEST_CHECK(memcmp(out, test_string, test_string_len-1) == 0);
964
965 TEST_CASE("Check (vp->vp_string == test_string)");
966 TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
967}
968
970{
971 fr_pair_t *vp;
972 char *out = NULL;
973
974 TEST_CASE("Find 'Test-String'");
976
977 TEST_CASE("Validating PAIR_VERIFY()");
979
980 TEST_CASE("Pre-allocate 1 byte of memory buffer using fr_pair_value_bstr_alloc()");
981 TEST_CHECK(fr_pair_value_bstr_alloc(vp, &out, 1, false) == 0);
982
983 TEST_CASE("Re-allocate (test_string_len-1) byte of memory buffer using fr_pair_value_bstr_realloc()");
985
986 TEST_CASE("Validating PAIR_VERIFY()");
988
989 TEST_CASE("Copy 'test_string' to the pre-allocated pointer");
991
992 TEST_CASE("Check (out == test_string)");
993 TEST_CHECK(memcmp(out, test_string, test_string_len-1) == 0);
994
995 TEST_CASE("Check (vp->vp_string == test_string)");
996 TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
997}
998
1000{
1001 fr_pair_t *vp;
1002
1003 TEST_CASE("Find 'Test-String'");
1005
1006 TEST_CASE("Validating PAIR_VERIFY()");
1007 PAIR_VERIFY(vp);
1008
1009 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrndup()");
1011
1012 TEST_CASE("Check (vp->vp_string == test_string)");
1013 TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
1014}
1015
1017{
1018 fr_pair_t *vp;
1019 char *copy_test_string;
1020
1021 TEST_CASE("Find 'Test-String'");
1023
1024 TEST_CASE("Validating PAIR_VERIFY()");
1025 PAIR_VERIFY(vp);
1026
1027 copy_test_string = talloc_strdup(vp, test_string);
1028 talloc_set_type(copy_test_string, char);
1029
1030 TEST_CASE("Copy content of 'copy_test_string' to attribute value using fr_pair_value_bstrdup_buffer()");
1031 TEST_CHECK(fr_pair_value_bstrdup_buffer(vp, copy_test_string, false) == 0);
1032
1033 TEST_CASE("Check (vp->vp_string == test_string)");
1034 TEST_CHECK(vp && strcmp(vp->vp_strvalue, copy_test_string) == 0);
1035
1036 talloc_free(copy_test_string);
1037}
1038
1040{
1041 fr_pair_t *vp;
1042 char *copy_test_string;
1043
1044 TEST_CASE("Find 'Test-String'");
1046
1047 TEST_CASE("Validating PAIR_VERIFY()");
1048 PAIR_VERIFY(vp);
1049
1050 copy_test_string = talloc_strdup(vp, test_string);
1051 talloc_set_type(copy_test_string, char);
1052
1053 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrndup_shallow()");
1054 TEST_CHECK(fr_pair_value_bstrndup_shallow(vp, copy_test_string, strlen(copy_test_string), true) == 0);
1055
1056 TEST_CASE("Check (vp->vp_string == copy_test_string)");
1057 TEST_CHECK(vp && strncmp(vp->vp_strvalue, test_string, test_string_len) == 0);
1058
1060}
1061
1063{
1064 fr_pair_t *vp;
1065 char *copy_test_string;
1066
1067 TEST_CASE("Find 'Test-String'");
1069
1070 TEST_CASE("Validating PAIR_VERIFY()");
1071 PAIR_VERIFY(vp);
1072
1073 copy_test_string = talloc_strdup(vp, test_string);
1074 talloc_set_type(copy_test_string, char);
1075
1076 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrdup_buffer_shallow()");
1077 TEST_CHECK(fr_pair_value_bstrdup_buffer_shallow(vp, copy_test_string, true) == 0);
1078
1079 TEST_CASE("Check (vp->vp_string == copy_test_string)");
1080 TEST_CHECK(vp && strncmp(vp->vp_strvalue, test_string, test_string_len) == 0);
1081
1083}
1084
1086{
1087 fr_pair_t *vp;
1088 uint8_t *out;
1089
1090 TEST_CASE("Find 'Test-Octets'");
1092
1093 TEST_CASE("Validating PAIR_VERIFY()");
1094 PAIR_VERIFY(vp);
1095
1096 TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
1098
1099 TEST_CASE("Copy 'test_octets' to the pre-allocated pointer");
1101
1102 TEST_CASE("Check (out == test_octets)");
1104
1105 TEST_CASE("Check (vp->vp_octets == test_octets)");
1106 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1107}
1108
1110{
1111 fr_pair_t *vp;
1112 uint8_t *out;
1113
1114 TEST_CASE("Find 'Test-Octets'");
1116
1117 TEST_CASE("Validating PAIR_VERIFY()");
1118 PAIR_VERIFY(vp);
1119
1120 TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
1122
1123 TEST_CASE("Copy 'test_octets' to the pre-allocated pointer");
1125
1126 TEST_CASE("Realloc pre-allocated pointer to fit extra 'test_octets' copy");
1128
1129 TEST_CASE("Copy 'test_octets' into the tail");
1131
1132 TEST_CASE("Check first chunk (out == test_octets)");
1134
1135 TEST_CHECK(vp != NULL);
1136
1137 TEST_CASE("Check first chunk (vp->vp_octets == test_octets)");
1138 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1139
1140 TEST_CASE("Check second chunk (out+NUM_ELEMENTS(test_octets) == test_octets)");
1142
1143 TEST_CASE("Check second chunk (vp->vp_octets+NUM_ELEMENTS(test_octets) == test_octets)");
1145}
1146
1148{
1149 fr_pair_t *vp;
1150
1151 TEST_CASE("Find 'Test-Octets'");
1153
1154 TEST_CASE("Validating PAIR_VERIFY()");
1155 PAIR_VERIFY(vp);
1156
1157 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup()");
1159
1160 TEST_CASE("Check (vp->vp_octets == test_octets)");
1161 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1162}
1163
1165{
1166 fr_pair_t *vp;
1167 uint8_t *copy_test_octets;
1168
1169 TEST_CASE("Find 'Test-Octets'");
1171
1172 TEST_CASE("Validating PAIR_VERIFY()");
1173 PAIR_VERIFY(vp);
1174
1175 copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1176 talloc_set_type(copy_test_octets, uint8_t);
1177
1178 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_buffer()");
1179 TEST_CHECK(fr_pair_value_memdup_buffer(vp, copy_test_octets, true) == 0);
1180
1181 TEST_CASE("Check (vp->vp_octets == test_octets)");
1182 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1183
1184 talloc_free(copy_test_octets);
1185}
1186
1188{
1189 fr_pair_t *vp;
1190 uint8_t *copy_test_octets;
1191
1192 TEST_CASE("Find 'Test-Octets'");
1194
1195 TEST_CASE("Validating PAIR_VERIFY()");
1196 PAIR_VERIFY(vp);
1197
1198 copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1199 talloc_set_type(copy_test_octets, uint8_t);
1200
1201 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_shallow()");
1202 TEST_CHECK(fr_pair_value_memdup_shallow(vp, copy_test_octets, NUM_ELEMENTS(test_octets), true) == 0);
1203
1204 TEST_CASE("Check (vp->vp_octets == test_octets)");
1205 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1206
1208}
1209
1211{
1212 fr_pair_t *vp;
1213 uint8_t *copy_test_octets;
1214
1215 TEST_CASE("Find 'Test-Octets'");
1217
1218 TEST_CASE("Validating PAIR_VERIFY()");
1219 PAIR_VERIFY(vp);
1220
1221 copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1222 talloc_set_type(copy_test_octets, uint8_t);
1223
1224 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_buffer_shallow()");
1225 TEST_CHECK(fr_pair_value_memdup_buffer_shallow(vp, copy_test_octets, true) == 0);
1226
1227 TEST_CASE("Check (vp->vp_octets == copy_test_octets)");
1228 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1229
1231}
1232
1234{
1235 fr_pair_t *vp;
1236 char const *var;
1237 char buf[20];
1238
1239 TEST_CASE("Find 'Test-Values'");
1241
1242 TEST_CASE("Validating PAIR_VERIFY()");
1243 PAIR_VERIFY(vp);
1244
1245 vp->vp_uint32 = 123;
1246
1247 TEST_CASE("Lookup enum value attribute using fr_pair_value_enum()");
1248
1249 TEST_CHECK((var = fr_pair_value_enum(vp, buf)) != NULL);
1250 TEST_MSG("Checking fr_pair_value_enum()");
1251
1252 TEST_CHECK(var && strcmp(var, "test123") == 0);
1253 TEST_MSG("Expected var == 'test123'");
1254}
1255
1257{
1258 fr_pair_t *vp;
1259 fr_value_box_t const *vb;
1260
1261 TEST_CASE("Find 'Test-Values'");
1263
1264 TEST_CASE("Validating PAIR_VERIFY()");
1265 PAIR_VERIFY(vp);
1266
1267 vp->vp_uint32 = 123;
1268
1269 TEST_CASE("Lookup enum value attribute using fr_pair_value_enum_box()");
1270
1272 TEST_MSG("Checking fr_pair_value_enum()");
1273
1274 TEST_CHECK(vb->vb_uint32 == 123);
1275 TEST_MSG("Expected vb->vb_uint32 == 123");
1276}
1277
1278/*
1279 * Regression test: fr_dict_by_protocol_substr() used to dereference
1280 * our_name.p without a bounds check after fr_sbuff_out_bstrncpy_allowed()
1281 * had consumed every byte. If the input sbuff was bounded by length
1282 * (rather than a NUL sentinel), that read was one byte past in->end.
1283 *
1284 * The buggy code:
1285 * if (*(our_name.p) && (*(our_name.p) != '.')) { return 0 with dict_def; }
1286 *
1287 * With the bug, an OOB byte equal to '.' or NUL would let execution
1288 * fall through to the hash lookup; an OOB byte of any other value
1289 * would take the early-return path and yield slen=0. Either way,
1290 * the read past in->end is undefined.
1291 *
1292 * We construct a sbuff where in->end points one byte before a known
1293 * non-NUL, non-'.' sentinel. Then we run the function with
1294 * `fr_dict_test`, which has been added to the protocol table so the
1295 * hash lookup will succeed when the bounds check is honoured.
1296 *
1297 * Bug: reads buf[4]='X', early-returns 0 with *out = dict_def (NULL).
1298 * Fix: bounds check trips, hash lookup finds "test", returns slen=4
1299 * with *out = fr_dict_test.
1300 */
1301extern int dict_protocol_add(fr_dict_t *dict);
1302
1304{
1305 char buf[8];
1306 fr_sbuff_t sbuff;
1307 fr_dict_t const *out_dict = NULL;
1308 fr_slen_t slen;
1309
1310 if (dict_protocol_add(test_dict) < 0) {
1311 TEST_CHECK_(0, "dict_protocol_add failed: %s", fr_strerror());
1312 return;
1313 }
1314
1315 memcpy(buf, "testXXXX", 8); /* "test" then sentinel bytes the buggy code would read */
1316 fr_sbuff_init_in(&sbuff, buf, (size_t)4); /* Only "test" is visible */
1317
1318 slen = fr_dict_by_protocol_substr(NULL, &out_dict, &sbuff, NULL);
1319
1320 TEST_CHECK(slen == 4);
1321 TEST_MSG("Expected slen=4 (matched 'test' protocol), got %zd", (ssize_t)slen);
1322
1323 TEST_CHECK(out_dict == test_dict);
1324 TEST_MSG("Expected out_dict==test_dict; OOB read of sentinel byte made the buggy code early-return with dict_def (NULL)");
1325}
1326
1327/*
1328 * Printing
1329 */
1330
1331/** Print one pair into a buffer, and compare it against what we expect
1332 *
1333 */
1334#define TEST_PRINT_PAIR(_func, _parent, _vp, _expected) \
1335do { \
1336 char buffer[1024]; \
1337 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer)); \
1338 ssize_t slen; \
1339\
1340 slen = _func(&sbuff, _parent, _vp); \
1341 TEST_CHECK(slen > 0); \
1342 TEST_MSG(#_func " returned %zd: %s", slen, fr_strerror()); \
1343\
1344 TEST_CHECK(strcmp(buffer, _expected) == 0); \
1345 TEST_MSG("expected: %s", _expected); \
1346 TEST_MSG("got : %s", buffer); \
1347} while (0)
1348
1349static void test_fr_pair_print(void)
1350{
1351 fr_pair_t *vp;
1352
1353 TEST_CASE("Print one leaf pair");
1355 if (!vp) return;
1357
1358 TEST_PRINT_PAIR(fr_pair_print, NULL, vp, "Test-String-0 = \"We love testing!\"");
1359
1360 TEST_CASE("Print one leaf pair, relative to its own parent");
1361 TEST_PRINT_PAIR(fr_pair_print, fr_dict_root(test_dict), vp, "Test-String-0 = \"We love testing!\"");
1362
1363 talloc_free(vp);
1364}
1365
1367{
1368 fr_pair_list_t list;
1369 fr_pair_t *leaf, *top;
1370 fr_pair_t const *name_vp;
1371 char buffer[1024];
1372 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1373
1374 fr_pair_list_init(&list);
1375
1376 TEST_CASE("Build Test-Nested-Top-TLV.Child-TLV.Leaf-String");
1378 if (!leaf) return;
1379
1380 TEST_CHECK((top = fr_pair_find_by_da(&list, NULL, fr_dict_attr_test_nested_top_tlv)) != NULL);
1381
1382 TEST_CASE("The full name is printed when there is no parent");
1383 name_vp = leaf;
1384 TEST_CHECK(fr_pair_print_name(&sbuff, NULL, &name_vp) > 0);
1385 TEST_CHECK(strcmp(buffer, "Test-Nested-Top-TLV-0.Child-TLV.Leaf-String = ") == 0);
1386 TEST_MSG("got: %s", buffer);
1387
1388 TEST_CASE("Naming a parent trims that much off the front");
1389 fr_sbuff_set_to_start(&sbuff);
1390 name_vp = leaf;
1392 TEST_CHECK(strcmp(buffer, "Leaf-String = ") == 0);
1393 TEST_MSG("got: %s", buffer);
1394
1395 fr_pair_list_free(&list);
1396}
1397
1399{
1400 fr_pair_t *vp;
1401 char buffer[1024];
1402 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1403
1405 if (!vp) return;
1407
1408 TEST_CASE("A bare word is printed without quotes");
1410 TEST_CHECK(strcmp(buffer, test_string) == 0);
1411 TEST_MSG("got: %s", buffer);
1412
1413 TEST_CASE("A double quoted string keeps its quotes");
1414 fr_sbuff_set_to_start(&sbuff);
1416 TEST_CHECK(strcmp(buffer, "\"We love testing!\"") == 0);
1417 TEST_MSG("got: %s", buffer);
1418
1419 talloc_free(vp);
1420}
1421
1423{
1424 fr_pair_t *vp;
1425
1426 TEST_CASE("A pair which holds no secret prints its value");
1428 if (!vp) return;
1430
1431 TEST_PRINT_PAIR(fr_pair_print_secure, NULL, vp, "Test-String-0 = \"We love testing!\"");
1432
1433 TEST_CASE("A pair which holds a secret prints a placeholder instead");
1434 fr_value_box_set_secret(&vp->data, true);
1435 TEST_PRINT_PAIR(fr_pair_print_secure, NULL, vp, "Test-String-0 = <<< secret >>>");
1436
1437 talloc_free(vp);
1438}
1439
1440/** fr_pair_print_secure() walks the children of a structural pair
1441 *
1442 * Each child but the last is followed by a separator, so the interesting
1443 * cases are no children, one child, and more than one.
1444 */
1446{
1447 fr_pair_t *tlv, *child;
1448
1449 TEST_CASE("A structural pair with no children");
1451 if (!tlv) return;
1452
1453 TEST_PRINT_PAIR(fr_pair_print_secure, NULL, tlv, "Test-TLV-0 = { }");
1454
1455 TEST_CASE("A structural pair with one child, which needs no separator");
1456 TEST_CHECK(fr_pair_append_by_da(tlv, &child, &tlv->vp_group, fr_dict_attr_test_tlv_string) == 0);
1457 TEST_CHECK(fr_pair_value_strdup(child, "one", false) == 0);
1458
1459 TEST_PRINT_PAIR(fr_pair_print_secure, NULL, tlv, "Test-TLV-0 = { String = \"one\" }");
1460
1461 TEST_CASE("A structural pair with two children, separated by a comma");
1462 TEST_CHECK(fr_pair_append_by_da(tlv, &child, &tlv->vp_group, fr_dict_attr_test_tlv_string) == 0);
1463 TEST_CHECK(fr_pair_value_strdup(child, "two", false) == 0);
1464
1466 "Test-TLV-0 = { String = \"one\", String = \"two\" }");
1467
1468 TEST_CASE("Secrets are hidden inside structural pairs, too");
1469 fr_value_box_set_secret(&child->data, true);
1471 "Test-TLV-0 = { String = \"one\", String = <<< secret >>> }");
1472
1473 talloc_free(tlv);
1474}
1475
1477{
1478 fr_pair_list_t list;
1479 fr_pair_t *vp;
1480 char buffer[1024] = "";
1481 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1482
1483 fr_pair_list_init(&list);
1484
1485 TEST_CASE("An empty list prints nothing");
1486 TEST_CHECK(fr_pair_list_print(&sbuff, NULL, &list) >= 0);
1487 TEST_CHECK(buffer[0] == '\0');
1488
1489 TEST_CASE("Two pairs are separated by a comma");
1491 TEST_CHECK(fr_pair_value_strdup(vp, "one", false) == 0);
1492
1494 vp->vp_uint32 = 2;
1495
1496 fr_sbuff_set_to_start(&sbuff);
1497 TEST_CHECK(fr_pair_list_print(&sbuff, NULL, &list) > 0);
1498 TEST_CHECK(strcmp(buffer, "Test-String-0 = \"one\", Test-Uint32-0 = 2") == 0);
1499 TEST_MSG("got: %s", buffer);
1500
1501 fr_pair_list_free(&list);
1502}
1503
1504/** fr_pair_debug() and fr_pair_list_debug() write to a FILE, not to an sbuff
1505 *
1506 */
1507static void test_fr_pair_debug(void)
1508{
1509 fr_pair_list_t list;
1510 fr_pair_t *vp;
1511 FILE *fp;
1512 char buffer[1024];
1513 size_t len;
1514
1515 fr_pair_list_init(&list);
1516
1518 TEST_CHECK(fr_pair_value_strdup(vp, "one", false) == 0);
1519
1520 TEST_CASE("fr_pair_debug() writes one pair");
1521 /* coverity[secure_temp] */
1522 TEST_CHECK((fp = tmpfile()) != NULL);
1523 if (!fp) return;
1524
1525 fr_pair_debug(fp, vp);
1526 rewind(fp);
1527 len = fread(buffer, 1, sizeof(buffer) - 1, fp);
1528 buffer[len] = '\0';
1529 fclose(fp);
1530
1531 TEST_CHECK(strstr(buffer, "Test-String") != NULL);
1532 TEST_MSG("got: %s", buffer);
1533 TEST_CHECK(strstr(buffer, "one") != NULL);
1534
1535 TEST_CASE("fr_pair_list_debug() writes the whole list");
1536 /* coverity[secure_temp] */
1537 TEST_CHECK((fp = tmpfile()) != NULL);
1538 if (!fp) return;
1539
1540 fr_pair_list_debug(fp, &list);
1541 rewind(fp);
1542 len = fread(buffer, 1, sizeof(buffer) - 1, fp);
1543 buffer[len] = '\0';
1544 fclose(fp);
1545
1546 TEST_CHECK(strstr(buffer, "Test-String") != NULL);
1547 TEST_MSG("got: %s", buffer);
1548
1549 fr_pair_list_free(&list);
1550}
1551
1553 /*
1554 * Regression tests
1555 */
1556 { "fr_dict_by_protocol_substr no overflow", test_fr_dict_by_protocol_substr_no_overflow },
1557
1558 /*
1559 * Allocation and management
1560 */
1561 { "fr_pair_afrom_da", test_fr_pair_afrom_da },
1562 { "fr_pair_afrom_child_num", test_fr_pair_afrom_child_num },
1563 { "fr_pair_afrom_da_nested", test_fr_pair_afrom_da_nested },
1564 { "fr_pair_copy", test_fr_pair_copy },
1565 { "fr_pair_steal", test_fr_pair_steal },
1566
1567 /* Searching and list modification */
1568 { "fr_dcursor_iter_by_da_init", test_fr_pair_dcursor_by_da_init },
1569 { "fr_pair_dcursor_by_ancestor_init", test_fr_pair_dcursor_by_ancestor_init },
1570 { "fr_pair_dcursor_value_init", test_fr_pair_dcursor_value_init },
1571 { "fr_pair_raw_afrom_pair", test_fr_pair_raw_afrom_pair },
1572 { "fr_pair_find_by_da_idx", test_fr_pair_find_by_da_idx },
1573 { "fr_pair_find_by_child_num_idx", test_fr_pair_find_by_child_num_idx },
1574 { "fr_pair_find_by_da_nested", test_fr_pair_find_by_da_nested },
1575 { "fr_pair_append", test_fr_pair_append },
1576 { "fr_pair_prepend_by_da", test_fr_pair_prepend_by_da },
1577 { "fr_pair_append_by_da_parent", test_fr_pair_append_by_da_parent },
1578 { "fr_pair_delete_by_child_num", test_fr_pair_delete_by_child_num },
1579 { "fr_pair_update_by_da_parent", test_fr_pair_update_by_da_parent },
1580 { "fr_pair_delete", test_fr_pair_delete },
1581 { "fr_pair_delete_by_da", test_fr_pair_delete_by_da },
1582 { "fr_pair_delete_by_da_nested", test_fr_pair_delete_by_da_nested },
1583
1584 /* Printing */
1585 { "fr_pair_print", test_fr_pair_print },
1586 { "fr_pair_print_name", test_fr_pair_print_name },
1587 { "fr_pair_print_value_quoted", test_fr_pair_print_value_quoted },
1588 { "fr_pair_print_secure", test_fr_pair_print_secure },
1589 { "fr_pair_print_secure children", test_fr_pair_print_secure_children },
1590 { "fr_pair_list_print", test_fr_pair_list_print },
1591 { "fr_pair_debug", test_fr_pair_debug },
1592
1593 /* Compare */
1594 { "fr_pair_cmp", test_fr_pair_cmp },
1595 { "fr_pair_list_cmp", test_fr_pair_list_cmp },
1596
1597 /* Lists */
1598 { "fr_pair_list_copy", test_fr_pair_list_copy },
1599 { "fr_pair_list_copy_by_da", test_fr_pair_list_copy_by_da },
1600 { "fr_pair_list_copy_by_ancestor", test_fr_pair_list_copy_by_ancestor },
1601 { "fr_pair_list_sort", test_fr_pair_list_sort },
1602
1603 /* Copy */
1604 { "fr_pair_value_copy", test_fr_pair_value_copy },
1605
1606
1607 /* parenting */
1608 { "test_fr_pair_nested_verify", test_fr_pair_nested_verify },
1609
1610 /* Strings */
1611 { "fr_pair_value_from_str", test_fr_pair_value_from_str },
1612 { "fr_pair_value_strdup", test_fr_pair_value_strdup },
1613 { "fr_pair_value_strdup_shallow", test_fr_pair_value_strdup_shallow },
1614 { "fr_pair_value_strtrim", test_fr_pair_value_strtrim },
1615 { "fr_pair_value_aprintf", test_fr_pair_value_aprintf },
1616
1617 /* Assign and manipulate binary-safe strings */
1618 { "fr_pair_value_bstr_alloc", test_fr_pair_value_bstr_alloc },
1619 { "fr_pair_value_bstr_realloc", test_fr_pair_value_bstr_realloc },
1620 { "fr_pair_value_bstrndup", test_fr_pair_value_bstrndup },
1621 { "fr_pair_value_bstrdup_buffer", test_fr_pair_value_bstrdup_buffer },
1622 { "fr_pair_value_bstrndup_shallow", test_fr_pair_value_bstrndup_shallow },
1623 { "fr_pair_value_bstrdup_buffer_shallow", test_fr_pair_value_bstrdup_buffer_shallow },
1624
1625 /* Assign and manipulate octets strings */
1626 { "fr_pair_value_mem_alloc", test_fr_pair_value_mem_alloc },
1627 { "fr_pair_value_mem_realloc", test_fr_pair_value_mem_realloc },
1628 { "fr_pair_value_memdup", test_fr_pair_value_memdup },
1629 { "fr_pair_value_memdup_buffer", test_fr_pair_value_memdup_buffer },
1630 { "fr_pair_value_memdup_shallow", test_fr_pair_value_memdup_shallow },
1631 { "fr_pair_value_memdup_buffer_shallow", test_fr_pair_value_memdup_buffer_shallow },
1632
1633 /* Enum functions */
1634 { "fr_pair_value_enum", test_fr_pair_value_enum },
1635 { "fr_pair_value_enum_box", test_fr_pair_value_enum_box },
1636
1638};
static int const char char buffer[256]
Definition acutest.h:576
#define TEST_CHECK(cond)
Definition acutest.h:87
#define TEST_CHECK_(cond,...)
Definition acutest.h:86
#define TEST_CASE(name)
Definition acutest.h:186
#define TEST_ASSERT(cond)
Definition acutest.h:110
#define TEST_TERMINATOR
Definition acutest.h:64
#define TEST_MSG(...)
Definition acutest.h:217
Common initialisation for acutest binaries.
#define NUM_ELEMENTS(_t)
Definition build.h:406
TALLOC_CTX * autofree
Definition common.c:29
static void * fr_dcursor_next(fr_dcursor_t *cursor)
Advanced the cursor to the next item.
Definition dcursor.h:288
#define MEM(x)
Definition debug.h:38
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition debug.h:272
bool fr_dict_attr_can_contain(fr_dict_attr_t const *parent, fr_dict_attr_t const *child)
See if a structural da is allowed to contain another da.
Definition dict_util.c:5297
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2720
fr_slen_t fr_dict_by_protocol_substr(fr_dict_attr_err_t *err, fr_dict_t const **out, fr_sbuff_t *name, fr_dict_t const *dict_def)
Look up a protocol name embedded in another string.
Definition dict_util.c:2820
fr_dict_attr_t const * fr_dict_attr_test_tlv_string
Definition dict_test.c:65
fr_dict_attr_t const * fr_dict_attr_test_nested_leaf_string
Definition dict_test.c:78
fr_dict_attr_t const * fr_dict_attr_test_enum
Definition dict_test.c:81
fr_dict_attr_t const * fr_dict_attr_test_date
Definition dict_test.c:58
fr_dict_attr_t const * fr_dict_attr_test_tlv
Definition dict_test.c:64
fr_dict_attr_t const * fr_dict_attr_test_nested_top_tlv
Definition dict_test.c:76
fr_dict_attr_t const * fr_dict_attr_test_uint32
Definition dict_test.c:47
fr_dict_attr_t const * fr_dict_attr_test_octets
Definition dict_test.c:31
fr_dict_attr_t const * fr_dict_attr_test_string
Definition dict_test.c:30
fr_dict_attr_t const * fr_dict_attr_test_ipv4_addr
Definition dict_test.c:33
fr_dict_attr_t const * fr_dict_attr_test_nested_child_tlv
Definition dict_test.c:77
int fr_dict_test_init(TALLOC_CTX *ctx, fr_dict_t **dict_p, fr_dict_test_attr_t const *test_defs)
Initialise a test dictionary and add our test_defs to it.
Definition dict_test.c:248
fr_dict_attr_t const * fr_dict_attr_test_uint8
Definition dict_test.c:45
fr_dict_attr_t const * fr_dict_attr_test_group
Definition dict_test.c:74
fr_dict_attr_t const * fr_dict_attr_test_nested_leaf_int32
Definition dict_test.c:79
fr_dict_attr_t const * fr_dict_attr_test_vsa
Definition dict_test.c:70
@ FR_TEST_ATTR_STRING
Definition dict_test.h:37
Test enumeration values.
Definition dict_test.h:92
Definition dwarf.c:424
#define __attribute__(x)
Definition filenames.h:38
talloc_free(hp)
#define fr_time()
Definition event.c:60
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
long int ssize_t
unsigned char uint8_t
ssize_t fr_slen_t
int fr_pair_value_memdup_buffer(fr_pair_t *vp, uint8_t const *src, bool tainted)
Copy data from a talloced buffer into an "octets" data type.
Definition pair.c:2924
int fr_pair_append_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
Alloc a new fr_pair_t (and append)
Definition pair.c:1417
int fr_pair_value_enum_box(fr_value_box_t const **out, fr_pair_t *vp)
Get value box of a VP, optionally prefer enum value.
Definition pair.c:3024
int fr_pair_value_aprintf(fr_pair_t *vp, char const *fmt,...)
Print data into an "string" data type.
Definition pair.c:2659
int fr_pair_delete_by_da_nested(fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete matching pairs from the specified list, and prune any empty branches.
Definition pair.c:1666
int fr_pair_list_copy(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from)
Duplicate a list of pairs.
Definition pair.c:2300
int fr_pair_value_memdup(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Copy data into an "octets" data type.
Definition pair.c:2894
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
Definition pair.c:783
fr_cmp_ret_t fr_pair_list_cmp(fr_pair_list_t const *a, fr_pair_list_t const *b)
Determine equality of two lists.
Definition pair.c:2028
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition pair.c:2595
int fr_pair_value_bstrdup_buffer_shallow(fr_pair_t *vp, char const *src, bool tainted)
Assign a string to a "string" type value pair.
Definition pair.c:2815
int fr_pair_value_from_str(fr_pair_t *vp, char const *value, size_t inlen, fr_sbuff_unescape_rules_t const *uerules, UNUSED bool tainted)
Convert string value to native attribute value.
Definition pair.c:2549
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition pair.c:708
fr_pair_t * fr_pair_find_by_child_num_idx(fr_pair_list_t const *list, fr_dict_attr_t const *parent, unsigned int attr, unsigned int idx)
Find the pair with the matching child attribute at a given index.
Definition pair.c:873
int fr_pair_cmp(fr_pair_t const *a, fr_pair_t const *b)
Compare two pairs, using the operator from "a".
Definition pair.c:1950
int fr_pair_value_bstrndup_shallow(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Assign a string to a "string" type value pair.
Definition pair.c:2795
int fr_pair_append(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the end of the list.
Definition pair.c:1298
int fr_pair_delete_by_da(fr_pair_list_t *list, fr_dict_attr_t const *da)
Delete matching pairs from the specified list.
Definition pair.c:1642
fr_cmp_ret_t fr_pair_cmp_by_da(void const *a, void const *b)
Order attributes by their da.
Definition pair.c:1797
fr_pair_t * fr_pair_find_by_da_idx(fr_pair_list_t const *list, fr_dict_attr_t const *da, unsigned int idx)
Find a pair with a matching da at a given index.
Definition pair.c:755
fr_pair_t * fr_pair_afrom_da(TALLOC_CTX *ctx, fr_dict_attr_t const *da)
Dynamically allocate a new attribute and assign a fr_dict_attr_t.
Definition pair.c:291
int fr_pair_update_by_da_parent(fr_pair_t *parent, fr_pair_t **out, fr_dict_attr_t const *da)
Return the first fr_pair_t matching the fr_dict_attr_t or alloc a new fr_pair_t and its subtree (and ...
Definition pair.c:1548
int fr_pair_list_copy_by_ancestor(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_dict_attr_t const *parent_da)
Duplicate pairs in a list where the da is a descendant of parent_da.
Definition pair.c:2432
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition pair.c:47
int fr_pair_value_mem_realloc(fr_pair_t *vp, uint8_t **out, size_t size)
Change the length of a buffer for a "octets" type value pair.
Definition pair.c:2868
char const * fr_pair_value_enum(fr_pair_t const *vp, char buff[20])
Return a const buffer for an enum type attribute.
Definition pair.c:2991
int fr_pair_value_bstrndup(fr_pair_t *vp, char const *src, size_t len, bool tainted)
Copy data into a "string" type value pair.
Definition pair.c:2744
int fr_pair_value_bstr_alloc(fr_pair_t *vp, char **out, size_t size, bool tainted)
Pre-allocate a memory buffer for a "string" type value pair.
Definition pair.c:2691
int fr_pair_value_bstr_realloc(fr_pair_t *vp, char **out, size_t size)
Change the length of a buffer for a "string" type value pair.
Definition pair.c:2716
void fr_pair_value_clear(fr_pair_t *vp)
Free/zero out value (or children) of a given VP.
Definition pair.c:2482
int fr_pair_delete(fr_pair_list_t *list, fr_pair_t *vp)
Remove fr_pair_t from a list and free.
Definition pair.c:1779
int fr_pair_append_by_da_parent(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
Alloc a new fr_pair_t, adding the parent attributes if required.
Definition pair.c:1474
int fr_pair_delete_by_child_num(fr_pair_list_t *list, fr_dict_attr_t const *parent, unsigned int attr)
Delete matching pairs from the specified list.
Definition pair.c:1761
int fr_pair_value_copy(fr_pair_t *dst, fr_pair_t *src)
Copy the value from one pair to another.
Definition pair.c:2512
int fr_pair_steal(TALLOC_CTX *ctx, fr_pair_t *vp)
Steal one VP.
Definition pair.c:538
int fr_pair_value_memdup_shallow(fr_pair_t *vp, uint8_t const *src, size_t len, bool tainted)
Assign a buffer to a "octets" type value pair.
Definition pair.c:2949
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition pair.c:504
int fr_pair_value_mem_alloc(fr_pair_t *vp, uint8_t **out, size_t size, bool tainted)
Pre-allocate a memory buffer for a "octets" type value pair.
Definition pair.c:2843
int fr_pair_value_strtrim(fr_pair_t *vp)
Trim the length of the string buffer to match the length of the C string.
Definition pair.c:2638
fr_pair_t * fr_pair_afrom_da_nested(TALLOC_CTX *ctx, fr_pair_list_t *list, fr_dict_attr_t const *da)
Create a pair (and all intermediate parents), and append it to the list.
Definition pair.c:481
int fr_pair_prepend(fr_pair_list_t *list, fr_pair_t *to_add)
Add a VP to the start of the list.
Definition pair.c:1267
fr_value_box_t * fr_pair_dcursor_value_init(fr_dcursor_t *cursor)
Initialises a special dcursor over a fr_pair_list_t, but which returns fr_value_box_t.
Definition pair.c:1204
int fr_pair_list_copy_by_da(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_dict_attr_t const *da)
Duplicate pairs in a list matching the specified da.
Definition pair.c:2388
int fr_pair_raw_afrom_pair(fr_pair_t *vp, uint8_t const *data, size_t data_len)
Mark malformed attribute as raw.
Definition pair.c:610
int fr_pair_value_memdup_buffer_shallow(fr_pair_t *vp, uint8_t const *src, bool tainted)
Assign a talloced buffer to a "octets" type value pair.
Definition pair.c:2969
int fr_pair_value_strdup_shallow(fr_pair_t *vp, char const *src, bool tainted)
Assign a buffer containing a nul terminated string to a vp, but don't copy it.
Definition pair.c:2619
int fr_pair_prepend_by_da(TALLOC_CTX *ctx, fr_pair_t **out, fr_pair_list_t *list, fr_dict_attr_t const *da)
Alloc a new fr_pair_t (and prepend)
Definition pair.c:1444
fr_pair_t * fr_pair_afrom_child_num(TALLOC_CTX *ctx, fr_dict_attr_t const *parent, unsigned int attr)
Create a new valuepair.
Definition pair.c:385
static fr_pair_list_t test_pairs
static fr_dict_t * test_dict
Helper functions for pair tests.
static int fr_pair_test_list_alloc_nested(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_test_attr_t const *test_defs)
static uint8_t test_octets[]
static int fr_pair_test_list_alloc(TALLOC_CTX *ctx, fr_pair_list_t *out, fr_dict_test_attr_t const *test_defs)
static size_t test_string_len
static char const * test_string
static void test_fr_pair_value_memdup_shallow(void)
static void test_fr_pair_print_secure(void)
TEST_LIST
static void test_fr_pair_list_copy_by_ancestor(void)
Definition pair_tests.c:712
static void test_fr_dict_by_protocol_substr_no_overflow(void)
static void test_fr_pair_afrom_child_num(void)
Definition pair_tests.c:110
static void test_fr_pair_value_aprintf(void)
Definition pair_tests.c:918
static void test_fr_pair_value_mem_realloc(void)
static void test_fr_pair_value_memdup_buffer(void)
static void test_fr_pair_value_enum_box(void)
static void test_fr_pair_value_bstrdup_buffer(void)
static void test_fr_pair_value_copy(void)
Definition pair_tests.c:800
static void test_fr_pair_delete(void)
Definition pair_tests.c:615
static void test_fr_pair_list_cmp(void)
Definition pair_tests.c:656
static void test_fr_pair_print(void)
static void test_fr_pair_copy(void)
Definition pair_tests.c:190
static void test_fr_pair_afrom_da(void)
Definition pair_tests.c:89
static void test_fr_pair_value_mem_alloc(void)
static void test_fr_pair_value_bstrndup(void)
Definition pair_tests.c:999
static void test_fr_pair_find_by_child_num_idx(void)
Definition pair_tests.c:371
static void test_fr_pair_value_bstrndup_shallow(void)
static void test_fr_pair_value_bstrdup_buffer_shallow(void)
static void test_fr_pair_print_secure_children(void)
fr_pair_print_secure() walks the children of a structural pair
static void test_fr_pair_list_copy(void)
Definition pair_tests.c:676
static void test_fr_pair_value_memdup_buffer_shallow(void)
static void test_fr_pair_value_bstr_realloc(void)
Definition pair_tests.c:969
static void test_fr_pair_dcursor_by_da_init(void)
Definition pair_tests.c:250
static void test_fr_pair_print_name(void)
static void test_fr_pair_delete_by_da(void)
Definition pair_tests.c:603
static void test_fr_pair_append(void)
Definition pair_tests.c:472
static void test_fr_pair_value_strdup_shallow(void)
Definition pair_tests.c:867
static void test_fr_pair_find_by_da_idx(void)
Definition pair_tests.c:357
static void test_fr_pair_nested_verify(void)
Definition pair_tests.c:183
static void test_fr_pair_print_value_quoted(void)
#define TEST_PRINT_PAIR(_func, _parent, _vp, _expected)
Print one pair into a buffer, and compare it against what we expect.
static void test_fr_pair_value_strtrim(void)
Definition pair_tests.c:895
static void test_fr_pair_value_enum(void)
static void test_fr_pair_value_bstr_alloc(void)
Definition pair_tests.c:942
static void test_fr_pair_list_sort(void)
Definition pair_tests.c:749
static void test_fr_pair_value_strdup(void)
Definition pair_tests.c:847
static void test_fr_pair_cmp(void)
Definition pair_tests.c:630
static void test_fr_pair_list_print(void)
static void test_fr_pair_prepend_by_da(void)
Definition pair_tests.c:561
static void test_fr_pair_afrom_da_nested(void)
Definition pair_tests.c:127
static void test_fr_pair_list_copy_by_da(void)
Definition pair_tests.c:691
static void test_fr_pair_value_from_str(void)
Definition pair_tests.c:827
static void test_fr_pair_append_by_da_parent(void)
Definition pair_tests.c:498
static void test_fr_pair_steal(void)
Definition pair_tests.c:214
static void test_fr_pair_delete_by_child_num(void)
Definition pair_tests.c:549
static void test_fr_pair_dcursor_by_ancestor_init(void)
Definition pair_tests.c:276
static void test_fr_pair_delete_by_da_nested(void)
Definition pair_tests.c:156
static void test_init(void)
Global initialisation.
Definition pair_tests.c:36
static void test_fr_pair_raw_afrom_pair(void)
Definition pair_tests.c:232
static void test_fr_pair_update_by_da_parent(void)
Definition pair_tests.c:580
static void test_fr_pair_find_by_da_nested(void)
Definition pair_tests.c:385
static void test_fr_pair_dcursor_value_init(void)
Definition pair_tests.c:302
static void test_fr_pair_value_memdup(void)
int dict_protocol_add(fr_dict_t *dict)
Add a protocol to the global protocol table.
Definition dict_util.c:1564
static void test_fr_pair_debug(void)
fr_pair_debug() and fr_pair_list_debug() write to a FILE, not to an sbuff
#define local_pairs
Convenience macro for accessing the state list.
Definition request.h:161
#define fr_sbuff_init_in(_out, _start, _len_or_end)
#define FR_SBUFF_OUT(_start, _len_or_end)
PUBLIC int snprintf(char *string, size_t length, char *format, va_alist)
Definition snprintf.c:689
fr_pair_value_bstrdup_buffer(vp, eap_session->identity, true)
fr_pair_t * vp
size_t strlcpy(char *dst, char const *src, size_t siz)
Definition strlcpy.c:34
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
fr_dict_attr_t const *_CONST da
Dictionary attribute defines the attribute number, vendor and type of the pair.
Definition pair.h:69
void * talloc_null_ctx(void)
Retrieve the current talloc NULL ctx.
Definition talloc.c:50
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition talloc.h:55
#define talloc_strdup(_ctx, _str)
Definition talloc.h:149
static int64_t fr_time_unwrap(fr_time_t time)
Definition time.h:146
"server local" time.
Definition time.h:69
@ T_BARE_WORD
Definition token.h:118
@ T_OP_EQ
Definition token.h:81
@ T_DOUBLE_QUOTED_STRING
Definition token.h:119
@ T_OP_CMP_EQ
Definition token.h:104
static unsigned count
Definition unittest.c:47
ssize_t fr_pair_print(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_t const *vp))
Print one attribute and value to a string.
Definition pair_print.c:232
void fr_pair_debug(FILE *fp, fr_pair_t const *pair)
Dumps a pair to the default logging destination - Useful for calling from debuggers.
Definition pair_print.c:449
#define fr_pair_dcursor_by_da_init(_cursor, _list, _da)
Initialise a cursor that will return only attributes matching the specified fr_dict_attr_t.
Definition pair.h:636
#define PAIR_VERIFY(_x)
Definition pair.h:205
fr_pair_t * fr_pair_list_next(fr_pair_list_t const *list, fr_pair_t const *item))
Get the next item in a valuepair list after a specific entry.
Definition pair_inline.c:69
#define fr_pair_list_foreach(_list_head, _iter)
Iterate over the contents of a fr_pair_list_t.
Definition pair.h:281
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
void fr_pair_list_debug(FILE *fp, fr_pair_list_t const *list)
Dumps a list to the default logging destination - Useful for calling from debuggers.
Definition pair_print.c:440
int fr_pair_list_sort(fr_pair_list_t *list, fr_cmp_t cmp)
Sort a doubly linked list of fr_pair_ts using merge sort.
static fr_slen_t quote ssize_t fr_pair_print_name(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_t const **vp_p)
Print an attribute name.
Definition pair_print.c:136
ssize_t fr_pair_print_value_quoted(fr_sbuff_t *out, fr_pair_t const *vp, fr_token_t quote)
Print the value of an attribute to a string.
Definition pair_print.c:59
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
Definition pair.h:601
fr_pair_t * fr_pair_list_head(fr_pair_list_t const *list)
Get the head of a valuepair list.
Definition pair_inline.c:42
#define fr_pair_dcursor_by_ancestor_init(_cursor, _list, _da)
Initialise a cursor that will return only attributes descended from the specified fr_dict_attr_t.
Definition pair.h:654
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
ssize_t fr_pair_print_secure(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_t const *vp))
Print one attribute and value to a string with escape rules.
Definition pair_print.c:267
ssize_t fr_pair_list_print(fr_sbuff_t *out, fr_dict_attr_t const *parent, fr_pair_list_t const *list)
Print a pair list.
Definition pair_print.c:316
static fr_slen_t parent
Definition pair.h:860
char const * fr_strerror(void)
Get the last library error.
Definition strerror.c:558
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition strerror.c:737
int fr_check_lib_magic(uint64_t magic)
Check if the application linking to the library has the correct magic number.
Definition version.c:40
#define RADIUSD_MAGIC_NUMBER
Definition version.h:81
void fr_value_box_set_secret(fr_value_box_t *box, bool secret)
Mark a box as holding a secret, or not.
Definition value.c:7510
fr_sbuff_unescape_rules_t const fr_value_unescape_double
Definition value.c:271
static size_t char ** out
Definition value.h:1062