The FreeRADIUS server $Id: a4e7f8c94e8038b7627bcf52356b7ed15955c1d7 $
Loading...
Searching...
No Matches
pair_nested_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
24static void test_init(void);
25#define TEST_GLOBAL_INIT test_init()
26
27#include "acutest_common_init.h"
28#include "acutest_helpers.h"
29#include "pair_test_helpers.h"
30
31#include <freeradius-devel/util/conf.h>
32#include <freeradius-devel/util/dict.h>
33#include <freeradius-devel/util/sbuff.h>
34
35static TALLOC_CTX *autofree;
38
39/** Global initialisation
40 */
41static void test_init(void)
42{
44 if (!autofree) {
45 error:
46#ifdef TEST_NESTED_PAIRS
47 fr_perror("pair_nested_tests");
48#else
49 fr_perror("pair_tests");
50#endif
51 fr_exit_now(EXIT_FAILURE);
52 }
53
54 /*
55 * Mismatch between the binary and the libraries it depends on
56 */
57 if (fr_check_lib_magic(RADIUSD_MAGIC_NUMBER) < 0) goto error;
58
59 if (fr_dict_test_init(autofree, &test_dict, NULL) < 0) goto error;
60
61 /* Initialize the "test_pairs" list */
63
64#ifdef TEST_NESTED_PAIRS
65 if (fr_pair_test_list_alloc_nested(autofree, &test_pairs, NULL) < 0) goto error;
66#else
67 if (fr_pair_test_list_alloc(autofree, &test_pairs, NULL) < 0) goto error;
68#endif
69}
70
71/*
72 * Tests functions
73 */
74static void test_fr_pair_afrom_da(void)
75{
77
78 TEST_CASE("Allocation using fr_pair_afrom_da");
80
81 TEST_CHECK(vp != NULL);
82 if (!vp) return;
83
85
86 TEST_CASE("Validating PAIR_VERIFY()");
88
89 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
90 TEST_MSG("Expected vp->vp_strvalue == test_string");
91
93}
94
96{
98 unsigned int attr = FR_TEST_ATTR_STRING;
99
100 TEST_CASE("Allocation using fr_pair_afrom_child_num");
102
103 TEST_CASE("Validating PAIR_VERIFY()");
105
106 TEST_CHECK(vp && vp->da->attr == FR_TEST_ATTR_STRING);
107 TEST_MSG("Expected attr(%u) == vp->da->attr(%u)", attr, vp->da->attr);
108
110}
111
113{
114 fr_pair_t *vp, *parent = NULL;
116
118
119 TEST_CASE("Allocation using fr_pair_afrom_da_nested");
121
123 TEST_MSG("Expected attr(%s) == vp->da->attr(%s)", fr_dict_attr_test_tlv_string->name, vp->da->name);
124
125 TEST_CASE("Validating PAIR_VERIFY()");
127
128 TEST_CASE("Top list does not have the tlv child attribute");
130
131 TEST_CASE("Top list does have the tlv attribute");
133 TEST_ASSERT(parent != NULL);
134
135 TEST_CASE("Parent list does have the tlv child attribute");
137
138 talloc_free(parent); /* not vp! */
139}
140
142{
143 int count;
144 fr_pair_t *vp, *parent = NULL;
146
148
149 TEST_CASE("Allocation using fr_pair_afrom_da_nested");
151
153 TEST_MSG("Expected attr(%s) == vp->da->attr(%s)", fr_dict_attr_test_tlv_string->name, vp->da->name);
154
155 TEST_CASE("Deleted nested pair");
157
158 TEST_CASE("Top list still has the tlv attribute");
160 TEST_ASSERT(parent != NULL);
161
162 TEST_CASE("Parent list does not have the tlv child attribute");
164
166}
167
173
174
175static void test_fr_pair_copy(void)
176{
177 fr_pair_t *vp, *copy;
178
179 TEST_CASE("Allocation using fr_pair_copy");
181
182 TEST_CASE("Validating PAIR_VERIFY()");
184
185 copy = fr_pair_copy(autofree, vp);
186
187 TEST_CASE("Validating PAIR_VERIFY()");
188 PAIR_VERIFY(copy);
189
190 vp->op = T_OP_CMP_EQ;
191
192 TEST_CASE("Compare fr_pair_cmp(copy == vp) should be TRUE");
193 TEST_CHECK(fr_pair_cmp(vp, copy) == 1);
194
196 talloc_free(copy);
197}
198
199static void test_fr_pair_steal(void)
200{
201 fr_pair_t *vp;
202 TALLOC_CTX *ctx = talloc_null_ctx();
203
204 TEST_CASE("Allocate a new attribute fr_pair_afrom_da");
206
207 TEST_CASE("Validating PAIR_VERIFY()");
209
210 TEST_CASE("Stealing 'vp' pair using fr_pair_steal()");
211 fr_pair_steal(autofree, vp); /* It should exit without memory-leaks */
212
213 TEST_CASE("Checking if talloc_parent(vp) == autofree");
214 TEST_CHECK(talloc_parent(vp) == autofree);
215}
216
218{
219 fr_pair_t *vp;
220 uint8_t value = 0;
221
222 TEST_CASE("Allocate a new attribute fr_pair_afrom_da");
224
225 TEST_CASE("Validating PAIR_VERIFY()");
227
228 TEST_CASE("Converting regular 'vp' as unknown");
230
231 TEST_CASE("Checking if a real 'raw' vp");
232 TEST_CHECK(vp && vp->vp_raw);
233}
234
236{
237 fr_pair_t *vp, *needle;
238 fr_dcursor_t cursor;
239
240 TEST_CASE("Searching for fr_dict_attr_test_uint32 using fr_pair_dcursor_by_da_init()");
241 needle = NULL;
243 vp;
244 vp = fr_dcursor_next(&cursor)) {
245 if (!needle) {
246 needle = vp;
247 continue;
248 }
249 TEST_CHECK(1 == 1); /* this never will be reached */
250 }
251
252 TEST_CASE("Validating PAIR_VERIFY()");
253
254 TEST_CHECK(needle != NULL);
255 if (needle) PAIR_VERIFY(needle);
256
257 TEST_CASE("Expected (needle->da == fr_dict_attr_test_uint32)");
258 TEST_CHECK(needle && needle->da == fr_dict_attr_test_uint32);
259}
260
262{
263 fr_pair_t *vp, *needle;
264 fr_dcursor_t cursor;
265
266 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()");
267 needle = NULL;
269 vp;
270 vp = fr_dcursor_next(&cursor)) {
271 TEST_CHECK(vp != NULL);
273 needle = vp;
274 continue;
275 }
276 }
277
278 TEST_CHECK(needle != NULL);
279
280 TEST_CASE("Validating PAIR_VERIFY()");
281 if (needle) PAIR_VERIFY(needle);
282
283 TEST_CASE("Expected (needle->da == fr_dict_attr_test_tlv_string)");
284 TEST_CHECK(needle && needle->da == fr_dict_attr_test_tlv_string);
285}
286
288{
289 int i = 0;
290 fr_value_box_t *box;
291 fr_dcursor_t cursor;
292 fr_pair_t *vp;
294
296
298 fr_pair_value_strdup(vp, "hello", false);
300
302 vp->vp_uint32 = 6809;
304
306 vp->vp_uint8 = 12;
308
309 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()");
310 for (box = fr_pair_dcursor_value_init(&cursor);
311 box;
312 box = fr_dcursor_next(&cursor), i++) {
313 switch (i) {
314 case 0:
315 TEST_CASE("First box is a string with value 'hello'");
316 TEST_CHECK(box->type == FR_TYPE_STRING);
317 TEST_CHECK(strcmp(box->vb_strvalue, "hello") == 0);
318 break;
319
320 case 1:
321 TEST_CASE("First box is a uint32 with value 6809");
322 TEST_CHECK(box->type == FR_TYPE_UINT32);
323 TEST_CHECK(box->vb_uint32 == 6809);
324 break;
325
326 case 2:
327 TEST_CASE("First box is a uint8 r with value 12");
328 TEST_CHECK(box->type == FR_TYPE_UINT8);
329 TEST_CHECK(box->vb_uint8 == 12);
330 break;
331
332 default:
333 TEST_CASE("Too many pairs");
334 TEST_CHECK(i < 3);
335 break;
336 }
337 }
338
340}
341
343{
344 fr_pair_t *vp;
345
346 TEST_CASE("Search for fr_dict_attr_test_string using fr_pair_find_by_da_idx()");
348
349 TEST_CASE("Validating PAIR_VERIFY()");
351
352 TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
354}
355
357{
358 fr_pair_t *vp;
359
360 TEST_CASE("Search for FR_TEST_ATTR_STRING using fr_pair_find_by_child_num_idx()");
362
363 TEST_CASE("Validating PAIR_VERIFY()");
365
366 TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
368}
369
371{
372 fr_pair_t *vp1, *vp2, *vp3, *vp4, *vp5, *vp_found;
374
376
377 /*
378 * Build a list with 2 TLV structures, each with different leaf nodes
379 */
383 fr_pair_append(&vp1->vp_group, vp2);
385 fr_pair_append(&vp2->vp_group, vp1);
389 fr_pair_append(&vp2->vp_group, vp3);
391 fr_pair_append(&vp3->vp_group, vp2);
392
394 TEST_CASE("Find child node in first TLV");
395 TEST_CHECK_PAIR(vp_found, vp1);
396
398 TEST_CASE("Find child node in second TLV");
399 TEST_CHECK_PAIR(vp_found, vp2);
400
401 /*
402 * Add third nested TLV with child of same type as first
403 */
407 fr_pair_append(&vp3->vp_group, vp4);
409 fr_pair_append(&vp4->vp_group, vp3);
410
411 /*
412 * A second attribute of the same type further down the list does
413 * not change which one is found.
414 */
416 TEST_CASE("Find child node in first TLV");
417 TEST_CHECK_PAIR(vp_found, vp1);
418
419 /*
420 * Add some "flat list" attributes
421 */
426
427 /*
428 * The search looks in the nesting before it looks at the flat
429 * list, so the nested attribute wins even though vp4 was
430 * prepended, and therefore comes first in the top level list.
431 */
433 TEST_CASE("A nested attribute is found before a flat one");
434 TEST_CHECK_PAIR(vp_found, vp1);
435
437
438 /*
439 * With no nesting to search, the flat attribute is the answer.
440 * This is the fallback at the end of fr_pair_find_by_da_nested().
441 */
443
446
448 TEST_CASE("Find a flat attribute when there is no nesting");
449 TEST_CHECK_PAIR(vp_found, vp5);
450
451 TEST_CASE("Find nothing when the attribute is not there at all");
453
455}
456
457static void test_fr_pair_append(void)
458{
459 fr_pair_t *vp;
461 size_t count = 0;
462
463 TEST_CASE("Add 3 pairs using fr_pair_append()");
464
466
473
474 /* lets' count */
476
477 TEST_CASE("Expected (count == 3)");
478 TEST_CHECK(count == 3);
479
481}
482
484{
485 fr_pair_t *leaf1, *leaf2, *found, *inter1, *inter2;
487 int ret;
488
490
491 TEST_CASE("Add nested attribute including parents");
493 TEST_CHECK(ret == 0);
494 TEST_CHECK(leaf1 != NULL);
495
496 TEST_CASE("Check nested attributes added");
498 TEST_ASSERT(found != NULL);
499 inter1 = found;
500 found = fr_pair_find_by_da(&inter1->vp_group, NULL, fr_dict_attr_test_nested_child_tlv);
501 TEST_ASSERT(found != NULL);
502 inter2 = found;
503 found = fr_pair_find_by_da(&inter2->vp_group, NULL, fr_dict_attr_test_nested_leaf_int32);
504 TEST_CHECK_PAIR(found, leaf1);
505
506 TEST_CASE("Ensure no flat list attribute created");
508 TEST_CHECK_PAIR(found, NULL);
509
510 TEST_CASE("Add additional nested attribute where parents exist");
512 TEST_CHECK(ret == 0);
513 TEST_CHECK(leaf2 != NULL);
514 TEST_CHECK(leaf2 != leaf1);
515
516 TEST_CASE("Check additional leaf added under existing parent");
517 found = fr_pair_find_by_da(&inter2->vp_group, NULL, fr_dict_attr_test_nested_leaf_string);
518 TEST_CHECK_PAIR(found, leaf2);
519
520 TEST_CASE("Check no extra parent attributes created");
522 TEST_CHECK_PAIR(found, inter1);
524 TEST_CHECK_PAIR(found, NULL);
525
526 found = fr_pair_find_by_da(&inter1->vp_group, NULL, fr_dict_attr_test_nested_child_tlv);
527 TEST_CHECK_PAIR(found, inter2);
528 found = fr_pair_find_by_da(&inter1->vp_group, inter2, fr_dict_attr_test_nested_child_tlv);
529 TEST_CHECK_PAIR(found, NULL);
530
532}
533
535{
536 TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete_by_child_num()");
538
539 TEST_CASE("The fr_dict_attr_test_string shouldn't exist in 'test_pairs'");
541
542 TEST_CASE("Add fr_dict_attr_test_string back into 'test_pairs'");
544}
545
547{
549 TALLOC_CTX *ctx = talloc_null_ctx();
550
552
553 TEST_CASE("Add using fr_pair_prepend_by_da()");
555
556 /* lets' count */
558 TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
560 }
561
563}
564
566{
567 fr_pair_t *vp, *group;
568
570 if (!group) return; /* quiet clang scan */
571
572 TEST_CASE("Update Add using fr_pair_prepend_by_da()");
573 TEST_CHECK(fr_pair_update_by_da_parent(group, &vp, fr_dict_attr_test_uint32) == 0); /* attribute doesn't exist in this group */
574 vp->vp_uint32 = 54321;
575
576 TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 54321)");
577 TEST_CHECK((vp = fr_pair_find_by_da(&group->vp_group, NULL, fr_dict_attr_test_uint32)) != NULL);
578
579 TEST_CASE("Validating PAIR_VERIFY()");
581
582 TEST_CASE("Expected (vp == 54321)");
583 TEST_CHECK(vp && vp->vp_uint32 == 54321);
584
585 talloc_free(group);
586}
587
589{
590 TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete_by_da()");
592
593 TEST_CASE("The fr_dict_attr_test_string shouldn't exist in 'test_pairs'");
595
596 TEST_CASE("Add fr_dict_attr_test_string back into 'test_pairs'");
598}
599
600static void test_fr_pair_delete(void)
601{
602 fr_pair_t *vp;
603
604 TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete()");
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_cmp(void)
616{
617 fr_pair_t *vp1, *vp2;
618
619 TEST_CASE("Create the vp1 'Test-Integer = 123'");
621
622 TEST_CASE("Validating PAIR_VERIFY()");
623 PAIR_VERIFY(vp1);
624
625 vp1->op = T_OP_EQ;
626 vp1->vp_uint32 = 123;
627
628 TEST_CASE("Create the vp2 'Test-Integer = 321'");
630
631 TEST_CASE("Validating PAIR_VERIFY()");
632 PAIR_VERIFY(vp2);
633
634 vp2->op = T_OP_CMP_EQ;
635 vp2->vp_uint32 = 321;
636
637 TEST_CASE("Compare fr_pair_cmp(vp1 == vp2) should be FALSE");
638 TEST_CHECK(fr_pair_cmp(vp1, vp2) == 0);
639}
640
641static void test_fr_pair_list_cmp(void)
642{
643 fr_pair_list_t local_pairs1, local_pairs2;
644
645 fr_pair_list_init(&local_pairs1);
646 fr_pair_list_init(&local_pairs2);
647
648 TEST_CASE("Create 'local_pairs1'");
649 TEST_CHECK(fr_pair_test_list_alloc(autofree, &local_pairs1, NULL) == 0);
650
651 TEST_CASE("Create 'local_pairs2'");
652 TEST_CHECK(fr_pair_test_list_alloc(autofree, &local_pairs2, NULL) == 0);
653
654 TEST_CASE("Check if 'local_pairs1' == 'local_pairs2' using fr_pair_list_cmp()");
655 TEST_CHECK(fr_pair_list_cmp(&local_pairs1, &local_pairs2) == 0);
656
657 fr_pair_list_free(&local_pairs1);
658 fr_pair_list_free(&local_pairs2);
659}
660
661static void test_fr_pair_list_copy(void)
662{
664
666
667 TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
669
670 TEST_CASE("Check if 'local_pairs' == 'test_pairs' using fr_pair_list_cmp()");
672
674}
675
677{
679
681
682 TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
684
685 TEST_CASE("The 'local_pairs' should have only fr_dict_attr_test_string");
687 TEST_CASE("Validating PAIR_VERIFY()");
689
690 TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
692 }
693
695}
696
698{
699 fr_pair_t *vp;
701
703
704 TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
706
707 TEST_CASE("The 'local_pairs' should have only one attribute in it");
709
710 TEST_CASE("The 'local_pairs' should have only fr_dict_attr_test_tlv_string (ancestor of 'Test-TLV-Root'");
712
713 TEST_CASE("Validating we copied the attribute");
714 TEST_CHECK(vp != NULL);
715 if (!vp) return;
716
717#ifdef TEST_NESTED_PAIRS
718 TEST_CASE("Expected copied attribute == fr_dict_attr_test_tlv)");
720#else
721 TEST_CASE("Expected copied attribute == fr_dict_attr_test_tlv_string)");
723#endif
724
725 TEST_CASE("Verifying the copied attribute");
727
728 TEST_CASE("Expecting nothing else in local list");
730
732}
733
734static void test_fr_pair_list_sort(void)
735{
736 fr_dcursor_t cursor;
737 fr_pair_t *vp;
739 TALLOC_CTX *ctx = talloc_null_ctx();
740
741 TEST_CASE("Create 'local_pairs' with 3 attributes not ordered");
743
744 TEST_CASE("Add fr_dict_attr_test_string back into 'local_pairs'");
749 TEST_CHECK(fr_pair_prepend_by_da(ctx, NULL, &local_pairs, fr_dict_attr_test_enum) == 0); // It will be go to the tail
751
752 /*
753 * FIXME - This test doesn't check for intra-type stability
754 */
755 TEST_CASE("Sorting 'local_pairs' by fr_pair_list_sort(local_pairs, fr_pair_cmp_by_da)");
757
758 TEST_CASE("1st (da == fr_dict_attr_test_string)");
759 TEST_CHECK((vp = fr_pair_dcursor_init(&cursor, &local_pairs)) != NULL);
761
762 TEST_CASE("2nd (da == fr_dict_attr_test_octets)");
763 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
765
766 TEST_CASE("3rd (da == fr_dict_attr_test_ipv4_addr)");
767 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
769
770 TEST_CASE("4th (da == fr_dict_attr_test_uint32)");
771 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
773
774 TEST_CASE("5th (da == fr_dict_attr_test_date)");
775 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
777
778 TEST_CASE("6th (da == fr_dict_attr_test_enum)");
779 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
781
783}
784
785static void test_fr_pair_value_copy(void)
786{
787 fr_pair_t *vp1, *vp2;
788
789 TEST_CASE("Create 'vp1' with Test-Integer = 123");
791 vp1->vp_uint32 = 123;
792
793 TEST_CASE("Validating PAIR_VERIFY()");
794 PAIR_VERIFY(vp1);
795
796 TEST_CASE("Create 'vp2'");
798
799 TEST_CASE("Validating PAIR_VERIFY()");
800 PAIR_VERIFY(vp2);
801
802 TEST_CASE("Copy 'vp1' to 'vp2' using fr_pair_value_copy()");
803 TEST_CHECK(fr_pair_value_copy(vp2, vp1) == 0);
804
805 TEST_CASE("Validating PAIR_VERIFY()");
806 PAIR_VERIFY(vp2);
807
808 TEST_CASE("Check (vp1 == vp2)");
809 TEST_CHECK(vp2->vp_uint32 == 123);
810}
811
813{
814 fr_pair_t *vp;
815
816 TEST_CASE("Find 'Test-String'");
818
819 TEST_CASE("Validating PAIR_VERIFY()");
821
822 TEST_CASE("Convert 'test_string' value to attribute value using fr_pair_value_from_str()");
824
825 TEST_CASE("Validating PAIR_VERIFY()");
827
828 TEST_CASE("Check (vp->vp_string == test_string)");
829 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
830}
831
833{
834 fr_pair_t *vp;
835
836 TEST_CASE("Find 'Test-String'");
838
839 TEST_CASE("Validating PAIR_VERIFY()");
841
842 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup()");
844
845 TEST_CASE("Validating PAIR_VERIFY()");
847
848 TEST_CASE("Check (vp->vp_string == test_string)");
849 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
850}
851
853{
854 fr_pair_t *vp, *nvp;
855 char *copy_test_string;
856
857 TEST_CASE("Find 'Test-String'");
859
860 TEST_CASE("Validating PAIR_VERIFY()");
862
863 MEM(nvp = fr_pair_copy(NULL, vp));
864
865 copy_test_string = talloc_strdup(nvp, test_string);
866 talloc_set_type(copy_test_string, char);
867
868 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup_shallow()");
869 TEST_CHECK(fr_pair_value_strdup_shallow(nvp, copy_test_string, true) == 0);
870
871 TEST_CASE("Validating PAIR_VERIFY()");
872 PAIR_VERIFY(nvp);
873
874 TEST_CASE("Check (vp->vp_string == copy_test_string)");
875 TEST_CHECK(nvp && strncmp(nvp->vp_strvalue, test_string, strlen(copy_test_string)) == 0);
876
877 talloc_free(nvp);
878}
879
881{
882 fr_pair_t *vp;
883
884 TEST_CASE("Find 'Test-String'");
886
887 TEST_CASE("Validating PAIR_VERIFY()");
889
890 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup_shallow()");
892
893 TEST_CASE("Trim the length of the string buffer using fr_pair_value_strtrim()");
895
896 TEST_CASE("Validating PAIR_VERIFY()");
898
899 TEST_CASE("Check (vp->vp_string == test_string)");
900 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
901}
902
904{
905 fr_pair_t *vp;
906 char fmt_test[64];
907 fr_time_t now = fr_time();
908
909 snprintf(fmt_test, sizeof(fmt_test), "Now is %"PRId64, fr_time_unwrap(now));
910
911 TEST_CASE("Find 'Test-String'");
913
914 TEST_CASE("Validating PAIR_VERIFY()");
916
917 TEST_CASE("Copy content of 'fmt_test' to attribute value using fr_pair_value_aprintf()");
918 TEST_CHECK(fr_pair_value_aprintf(vp, "Now is %"PRId64, fr_time_unwrap(now)) == 0);
919
920 TEST_CASE("Validating PAIR_VERIFY()");
922
923 TEST_CASE("Check (vp->vp_string == fmt_test)");
924 TEST_CHECK(vp && strcmp(vp->vp_strvalue, fmt_test) == 0);
925}
926
928{
929 fr_pair_t *vp;
930 char *out = NULL;
931
932 TEST_CASE("Find 'Test-String'");
934
935 TEST_CASE("Validating PAIR_VERIFY()");
937
938 TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
940
941 TEST_CASE("Validating PAIR_VERIFY()");
943
944 TEST_CASE("Copy 'test_string' to the pre-allocated pointer");
946
947 TEST_CASE("Check (out == test_string)");
948 TEST_CHECK(memcmp(out, test_string, test_string_len-1) == 0);
949
950 TEST_CASE("Check (vp->vp_string == test_string)");
951 TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
952}
953
955{
956 fr_pair_t *vp;
957 char *out = NULL;
958
959 TEST_CASE("Find 'Test-String'");
961
962 TEST_CASE("Validating PAIR_VERIFY()");
964
965 TEST_CASE("Pre-allocate 1 byte of memory buffer using fr_pair_value_bstr_alloc()");
966 TEST_ASSERT(fr_pair_value_bstr_alloc(vp, &out, 1, false) == 0);
967
968 TEST_CASE("Re-allocate (test_string_len-1) byte of memory buffer using fr_pair_value_bstr_realloc()");
970
971 TEST_CASE("Validating PAIR_VERIFY()");
973
974 TEST_CASE("Copy 'test_string' to the pre-allocated pointer");
976
977 TEST_CASE("Check (out == test_string)");
978 TEST_CHECK(memcmp(out, test_string, test_string_len-1) == 0);
979
980 TEST_CASE("Check (vp->vp_string == test_string)");
981 TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
982}
983
985{
986 fr_pair_t *vp;
987
988 TEST_CASE("Find 'Test-String'");
990
991 TEST_CASE("Validating PAIR_VERIFY()");
993
994 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrndup()");
996
997 TEST_CASE("Check (vp->vp_string == test_string)");
998 TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
999}
1000
1002{
1003 fr_pair_t *vp;
1004 char *copy_test_string;
1005
1006 TEST_CASE("Find 'Test-String'");
1008
1009 TEST_CASE("Validating PAIR_VERIFY()");
1010 PAIR_VERIFY(vp);
1011
1012 copy_test_string = talloc_strdup(vp, test_string);
1013 talloc_set_type(copy_test_string, char);
1014
1015 TEST_CASE("Copy content of 'copy_test_string' to attribute value using fr_pair_value_bstrdup_buffer()");
1016 TEST_CHECK(fr_pair_value_bstrdup_buffer(vp, copy_test_string, false) == 0);
1017
1018 TEST_CASE("Check (vp->vp_string == test_string)");
1019 TEST_CHECK(vp && strcmp(vp->vp_strvalue, copy_test_string) == 0);
1020
1021 talloc_free(copy_test_string);
1022}
1023
1025{
1026 fr_pair_t *vp;
1027 char *copy_test_string;
1028
1029 TEST_CASE("Find 'Test-String'");
1031
1032 TEST_CASE("Validating PAIR_VERIFY()");
1033 PAIR_VERIFY(vp);
1034
1035 copy_test_string = talloc_strdup(vp, test_string);
1036 talloc_set_type(copy_test_string, char);
1037
1038 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrndup_shallow()");
1039 TEST_CHECK(fr_pair_value_bstrndup_shallow(vp, copy_test_string, strlen(copy_test_string), true) == 0);
1040
1041 TEST_CASE("Check (vp->vp_string == copy_test_string)");
1042 TEST_CHECK(vp && strncmp(vp->vp_strvalue, test_string, test_string_len) == 0);
1043
1045}
1046
1048{
1049 fr_pair_t *vp;
1050 char *copy_test_string;
1051
1052 TEST_CASE("Find 'Test-String'");
1054
1055 TEST_CASE("Validating PAIR_VERIFY()");
1056 PAIR_VERIFY(vp);
1057
1058 copy_test_string = talloc_strdup(vp, test_string);
1059 talloc_set_type(copy_test_string, char);
1060
1061 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrdup_buffer_shallow()");
1062 TEST_CHECK(fr_pair_value_bstrdup_buffer_shallow(vp, copy_test_string, true) == 0);
1063
1064 TEST_CASE("Check (vp->vp_string == copy_test_string)");
1065 TEST_CHECK(vp && strncmp(vp->vp_strvalue, test_string, test_string_len) == 0);
1066
1068}
1069
1071{
1072 fr_pair_t *vp;
1073 uint8_t *out;
1074
1075 TEST_CASE("Find 'Test-Octets'");
1077
1078 TEST_CASE("Validating PAIR_VERIFY()");
1079 PAIR_VERIFY(vp);
1080
1081 TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
1083
1084 TEST_CASE("Copy 'test_octets' to the pre-allocated pointer");
1086
1087 TEST_CASE("Check (out == test_octets)");
1089
1090 TEST_CASE("Check (vp->vp_octets == test_octets)");
1091 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1092}
1093
1095{
1096 fr_pair_t *vp;
1097 uint8_t *out;
1098
1099 TEST_CASE("Find 'Test-Octets'");
1101
1102 TEST_CASE("Validating PAIR_VERIFY()");
1103 PAIR_VERIFY(vp);
1104
1105 TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
1107
1108 TEST_CASE("Copy 'test_octets' to the pre-allocated pointer");
1110
1111 TEST_CASE("Realloc pre-allocated pointer to fit extra 'test_octets' copy");
1113
1114 TEST_CASE("Copy 'test_octets' into the tail");
1116
1117 TEST_CASE("Check first chunk (out == test_octets)");
1119
1120 TEST_CHECK(vp != NULL);
1121
1122 TEST_CASE("Check first chunk (vp->vp_octets == test_octets)");
1123 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1124
1125 TEST_CASE("Check second chunk (out+NUM_ELEMENTS(test_octets) == test_octets)");
1127
1128 TEST_CASE("Check second chunk (vp->vp_octets+NUM_ELEMENTS(test_octets) == test_octets)");
1130}
1131
1133{
1134 fr_pair_t *vp;
1135
1136 TEST_CASE("Find 'Test-Octets'");
1138
1139 TEST_CASE("Validating PAIR_VERIFY()");
1140 PAIR_VERIFY(vp);
1141
1142 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup()");
1144
1145 TEST_CASE("Check (vp->vp_octets == test_octets)");
1146 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1147}
1148
1150{
1151 fr_pair_t *vp;
1152 uint8_t *copy_test_octets;
1153
1154 TEST_CASE("Find 'Test-Octets'");
1156
1157 TEST_CASE("Validating PAIR_VERIFY()");
1158 PAIR_VERIFY(vp);
1159
1160 copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1161 talloc_set_type(copy_test_octets, uint8_t);
1162
1163 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_buffer()");
1164 TEST_CHECK(fr_pair_value_memdup_buffer(vp, copy_test_octets, true) == 0);
1165
1166 TEST_CASE("Check (vp->vp_octets == test_octets)");
1167 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1168
1169 talloc_free(copy_test_octets);
1170}
1171
1173{
1174 fr_pair_t *vp;
1175 uint8_t *copy_test_octets;
1176
1177 TEST_CASE("Find 'Test-Octets'");
1179
1180 TEST_CASE("Validating PAIR_VERIFY()");
1181 PAIR_VERIFY(vp);
1182
1183 copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1184 talloc_set_type(copy_test_octets, uint8_t);
1185
1186 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_shallow()");
1187 TEST_CHECK(fr_pair_value_memdup_shallow(vp, copy_test_octets, NUM_ELEMENTS(test_octets), true) == 0);
1188
1189 TEST_CASE("Check (vp->vp_octets == test_octets)");
1190 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1191
1193}
1194
1196{
1197 fr_pair_t *vp;
1198 uint8_t *copy_test_octets;
1199
1200 TEST_CASE("Find 'Test-Octets'");
1202
1203 TEST_CASE("Validating PAIR_VERIFY()");
1204 PAIR_VERIFY(vp);
1205
1206 copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1207 talloc_set_type(copy_test_octets, uint8_t);
1208
1209 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_buffer_shallow()");
1210 TEST_CHECK(fr_pair_value_memdup_buffer_shallow(vp, copy_test_octets, true) == 0);
1211
1212 TEST_CASE("Check (vp->vp_octets == copy_test_octets)");
1213 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1214
1216}
1217
1219{
1220 fr_pair_t *vp;
1221 char const *var;
1222 char buf[20];
1223
1224 TEST_CASE("Find 'Test-Values'");
1226
1227 TEST_CASE("Validating PAIR_VERIFY()");
1228 PAIR_VERIFY(vp);
1229
1230 vp->vp_uint32 = 123;
1231
1232 TEST_CASE("Lookup enum value attribute using fr_pair_value_enum()");
1233
1234 TEST_CHECK((var = fr_pair_value_enum(vp, buf)) != NULL);
1235 TEST_MSG("Checking fr_pair_value_enum()");
1236
1237 TEST_CHECK(var && strcmp(var, "test123") == 0);
1238 TEST_MSG("Expected var == 'test123'");
1239}
1240
1242{
1243 fr_pair_t *vp;
1244 fr_value_box_t const *vb;
1245
1246 TEST_CASE("Find 'Test-Values'");
1248
1249 TEST_CASE("Validating PAIR_VERIFY()");
1250 PAIR_VERIFY(vp);
1251
1252 vp->vp_uint32 = 123;
1253
1254 TEST_CASE("Lookup enum value attribute using fr_pair_value_enum_box()");
1255
1257 TEST_MSG("Checking fr_pair_value_enum()");
1258
1259 TEST_CHECK(vb->vb_uint32 == 123);
1260 TEST_MSG("Expected vb->vb_uint32 == 123");
1261}
1262
1263/*
1264 * Regression test: fr_dict_by_protocol_substr() used to dereference
1265 * our_name.p without a bounds check after fr_sbuff_out_bstrncpy_allowed()
1266 * had consumed every byte. If the input sbuff was bounded by length
1267 * (rather than a NUL sentinel), that read was one byte past in->end.
1268 *
1269 * The buggy code:
1270 * if (*(our_name.p) && (*(our_name.p) != '.')) { return 0 with dict_def; }
1271 *
1272 * With the bug, an OOB byte equal to '.' or NUL would let execution
1273 * fall through to the hash lookup; an OOB byte of any other value
1274 * would take the early-return path and yield slen=0. Either way,
1275 * the read past in->end is undefined.
1276 *
1277 * We construct a sbuff where in->end points one byte before a known
1278 * non-NUL, non-'.' sentinel. Then we run the function with
1279 * `fr_dict_test`, which has been added to the protocol table so the
1280 * hash lookup will succeed when the bounds check is honoured.
1281 *
1282 * Bug: reads buf[4]='X', early-returns 0 with *out = dict_def (NULL).
1283 * Fix: bounds check trips, hash lookup finds "test", returns slen=4
1284 * with *out = fr_dict_test.
1285 */
1286extern int dict_protocol_add(fr_dict_t *dict);
1287
1289{
1290 char buf[8];
1291 fr_sbuff_t sbuff;
1292 fr_dict_t const *out_dict = NULL;
1293 fr_slen_t slen;
1294
1295 if (dict_protocol_add(test_dict) < 0) {
1296 TEST_CHECK_(0, "dict_protocol_add failed: %s", fr_strerror());
1297 return;
1298 }
1299
1300 memcpy(buf, "testXXXX", 8); /* "test" then sentinel bytes the buggy code would read */
1301 fr_sbuff_init_in(&sbuff, buf, (size_t)4); /* Only "test" is visible */
1302
1303 slen = fr_dict_by_protocol_substr(NULL, &out_dict, &sbuff, NULL);
1304
1305 TEST_CHECK(slen == 4);
1306 TEST_MSG("Expected slen=4 (matched 'test' protocol), got %zd", (ssize_t)slen);
1307
1308 TEST_CHECK(out_dict == test_dict);
1309 TEST_MSG("Expected out_dict==test_dict; OOB read of sentinel byte made the buggy code early-return with dict_def (NULL)");
1310}
1311
1312/*
1313 * Printing
1314 */
1315
1316/** Print one pair into a buffer, and compare it against what we expect
1317 *
1318 */
1319#define TEST_PRINT_PAIR(_func, _parent, _vp, _expected) \
1320do { \
1321 char buffer[1024]; \
1322 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer)); \
1323 ssize_t slen; \
1324\
1325 slen = _func(&sbuff, _parent, _vp); \
1326 TEST_CHECK(slen > 0); \
1327 TEST_MSG(#_func " returned %zd: %s", slen, fr_strerror()); \
1328\
1329 TEST_CHECK(strcmp(buffer, _expected) == 0); \
1330 TEST_MSG("expected: %s", _expected); \
1331 TEST_MSG("got : %s", buffer); \
1332} while (0)
1333
1334static void test_fr_pair_print(void)
1335{
1336 fr_pair_t *vp;
1337
1338 TEST_CASE("Print one leaf pair");
1340 if (!vp) return;
1342
1343 TEST_PRINT_PAIR(fr_pair_print, NULL, vp, "Test-String-0 = \"We love testing!\"");
1344
1345 TEST_CASE("Print one leaf pair, relative to its own parent");
1346 TEST_PRINT_PAIR(fr_pair_print, fr_dict_root(test_dict), vp, "Test-String-0 = \"We love testing!\"");
1347
1348 talloc_free(vp);
1349}
1350
1352{
1353 fr_pair_list_t list;
1354 fr_pair_t *leaf, *top;
1355 fr_pair_t const *name_vp;
1356 char buffer[1024];
1357 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1358
1359 fr_pair_list_init(&list);
1360
1361 TEST_CASE("Build Test-Nested-Top-TLV.Child-TLV.Leaf-String");
1363 if (!leaf) return;
1364
1365 TEST_CHECK((top = fr_pair_find_by_da(&list, NULL, fr_dict_attr_test_nested_top_tlv)) != NULL);
1366
1367 TEST_CASE("The full name is printed when there is no parent");
1368 name_vp = leaf;
1369 TEST_CHECK(fr_pair_print_name(&sbuff, NULL, &name_vp) > 0);
1370 TEST_CHECK(strcmp(buffer, "Test-Nested-Top-TLV-0.Child-TLV.Leaf-String = ") == 0);
1371 TEST_MSG("got: %s", buffer);
1372
1373 TEST_CASE("Naming a parent trims that much off the front");
1374 fr_sbuff_set_to_start(&sbuff);
1375 name_vp = leaf;
1377 TEST_CHECK(strcmp(buffer, "Leaf-String = ") == 0);
1378 TEST_MSG("got: %s", buffer);
1379
1380 fr_pair_list_free(&list);
1381}
1382
1384{
1385 fr_pair_t *vp;
1386 char buffer[1024];
1387 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1388
1390 if (!vp) return;
1392
1393 TEST_CASE("A bare word is printed without quotes");
1395 TEST_CHECK(strcmp(buffer, test_string) == 0);
1396 TEST_MSG("got: %s", buffer);
1397
1398 TEST_CASE("A double quoted string keeps its quotes");
1399 fr_sbuff_set_to_start(&sbuff);
1401 TEST_CHECK(strcmp(buffer, "\"We love testing!\"") == 0);
1402 TEST_MSG("got: %s", buffer);
1403
1404 talloc_free(vp);
1405}
1406
1408{
1409 fr_pair_t *vp;
1410
1411 TEST_CASE("A pair which holds no secret prints its value");
1413 if (!vp) return;
1415
1416 TEST_PRINT_PAIR(fr_pair_print_secure, NULL, vp, "Test-String-0 = \"We love testing!\"");
1417
1418 TEST_CASE("A pair which holds a secret prints a placeholder instead");
1419 fr_value_box_set_secret(&vp->data, true);
1420 TEST_PRINT_PAIR(fr_pair_print_secure, NULL, vp, "Test-String-0 = <<< secret >>>");
1421
1422 talloc_free(vp);
1423}
1424
1425/** fr_pair_print_secure() walks the children of a structural pair
1426 *
1427 * Each child but the last is followed by a separator, so the interesting
1428 * cases are no children, one child, and more than one.
1429 */
1431{
1432 fr_pair_t *tlv, *child;
1433
1434 TEST_CASE("A structural pair with no children");
1436 if (!tlv) return;
1437
1438 TEST_PRINT_PAIR(fr_pair_print_secure, NULL, tlv, "Test-TLV-0 = { }");
1439
1440 TEST_CASE("A structural pair with one child, which needs no separator");
1441 TEST_CHECK(fr_pair_append_by_da(tlv, &child, &tlv->vp_group, fr_dict_attr_test_tlv_string) == 0);
1442 TEST_CHECK(fr_pair_value_strdup(child, "one", false) == 0);
1443
1444 TEST_PRINT_PAIR(fr_pair_print_secure, NULL, tlv, "Test-TLV-0 = { String = \"one\" }");
1445
1446 TEST_CASE("A structural pair with two children, separated by a comma");
1447 TEST_CHECK(fr_pair_append_by_da(tlv, &child, &tlv->vp_group, fr_dict_attr_test_tlv_string) == 0);
1448 TEST_CHECK(fr_pair_value_strdup(child, "two", false) == 0);
1449
1451 "Test-TLV-0 = { String = \"one\", String = \"two\" }");
1452
1453 TEST_CASE("Secrets are hidden inside structural pairs, too");
1454 fr_value_box_set_secret(&child->data, true);
1456 "Test-TLV-0 = { String = \"one\", String = <<< secret >>> }");
1457
1458 talloc_free(tlv);
1459}
1460
1462{
1463 fr_pair_list_t list;
1464 fr_pair_t *vp;
1465 char buffer[1024] = "";
1466 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1467
1468 fr_pair_list_init(&list);
1469
1470 TEST_CASE("An empty list prints nothing");
1471 TEST_CHECK(fr_pair_list_print(&sbuff, NULL, &list) >= 0);
1472 TEST_CHECK(buffer[0] == '\0');
1473
1474 TEST_CASE("Two pairs are separated by a comma");
1476 TEST_CHECK(fr_pair_value_strdup(vp, "one", false) == 0);
1477
1479 vp->vp_uint32 = 2;
1480
1481 fr_sbuff_set_to_start(&sbuff);
1482 TEST_CHECK(fr_pair_list_print(&sbuff, NULL, &list) > 0);
1483 TEST_CHECK(strcmp(buffer, "Test-String-0 = \"one\", Test-Uint32-0 = 2") == 0);
1484 TEST_MSG("got: %s", buffer);
1485
1486 fr_pair_list_free(&list);
1487}
1488
1489/** fr_pair_debug() and fr_pair_list_debug() write to a FILE, not to an sbuff
1490 *
1491 */
1492static void test_fr_pair_debug(void)
1493{
1494 fr_pair_list_t list;
1495 fr_pair_t *vp;
1496 FILE *fp;
1497 char buffer[1024];
1498
1499 fr_pair_list_init(&list);
1500
1502 TEST_CHECK(fr_pair_value_strdup(vp, "one", false) == 0);
1503
1504 TEST_CASE("fr_pair_debug() writes one pair");
1505 memset(buffer, 0, sizeof(buffer));
1506 TEST_CHECK((fp = fmemopen(buffer, sizeof(buffer) - 1, "w")) != NULL);
1507 if (!fp) return;
1508
1509 fr_pair_debug(fp, vp);
1510 fclose(fp);
1511
1512 TEST_CHECK(strstr(buffer, "Test-String") != NULL);
1513 TEST_MSG("got: %s", buffer);
1514 TEST_CHECK(strstr(buffer, "one") != NULL);
1515
1516 TEST_CASE("fr_pair_list_debug() writes the whole list");
1517 memset(buffer, 0, sizeof(buffer));
1518 TEST_CHECK((fp = fmemopen(buffer, sizeof(buffer) - 1, "w")) != NULL);
1519 if (!fp) return;
1520
1521 fr_pair_list_debug(fp, &list);
1522 fclose(fp);
1523
1524 TEST_CHECK(strstr(buffer, "Test-String") != NULL);
1525 TEST_MSG("got: %s", buffer);
1526
1527 fr_pair_list_free(&list);
1528}
1529
1531 /*
1532 * Regression tests
1533 */
1534 { "fr_dict_by_protocol_substr no overflow", test_fr_dict_by_protocol_substr_no_overflow },
1535
1536 /*
1537 * Allocation and management
1538 */
1539 { "fr_pair_afrom_da", test_fr_pair_afrom_da },
1540 { "fr_pair_afrom_child_num", test_fr_pair_afrom_child_num },
1541 { "fr_pair_afrom_da_nested", test_fr_pair_afrom_da_nested },
1542 { "fr_pair_copy", test_fr_pair_copy },
1543 { "fr_pair_steal", test_fr_pair_steal },
1544
1545 /* Searching and list modification */
1546 { "fr_dcursor_iter_by_da_init", test_fr_pair_dcursor_by_da_init },
1547 { "fr_pair_dcursor_by_ancestor_init", test_fr_pair_dcursor_by_ancestor_init },
1548 { "fr_pair_dcursor_value_init", test_fr_pair_dcursor_value_init },
1549 { "fr_pair_raw_afrom_pair", test_fr_pair_raw_afrom_pair },
1550 { "fr_pair_find_by_da_idx", test_fr_pair_find_by_da_idx },
1551 { "fr_pair_find_by_child_num_idx", test_fr_pair_find_by_child_num_idx },
1552 { "fr_pair_find_by_da_nested", test_fr_pair_find_by_da_nested },
1553 { "fr_pair_append", test_fr_pair_append },
1554 { "fr_pair_prepend_by_da", test_fr_pair_prepend_by_da },
1555 { "fr_pair_append_by_da_parent", test_fr_pair_append_by_da_parent },
1556 { "fr_pair_delete_by_child_num", test_fr_pair_delete_by_child_num },
1557 { "fr_pair_update_by_da_parent", test_fr_pair_update_by_da_parent },
1558 { "fr_pair_delete", test_fr_pair_delete },
1559 { "fr_pair_delete_by_da", test_fr_pair_delete_by_da },
1560 { "fr_pair_delete_by_da_nested", test_fr_pair_delete_by_da_nested },
1561
1562 /* Printing */
1563 { "fr_pair_print", test_fr_pair_print },
1564 { "fr_pair_print_name", test_fr_pair_print_name },
1565 { "fr_pair_print_value_quoted", test_fr_pair_print_value_quoted },
1566 { "fr_pair_print_secure", test_fr_pair_print_secure },
1567 { "fr_pair_print_secure children", test_fr_pair_print_secure_children },
1568 { "fr_pair_list_print", test_fr_pair_list_print },
1569 { "fr_pair_debug", test_fr_pair_debug },
1570
1571 /* Compare */
1572 { "fr_pair_cmp", test_fr_pair_cmp },
1573 { "fr_pair_list_cmp", test_fr_pair_list_cmp },
1574
1575 /* Lists */
1576 { "fr_pair_list_copy", test_fr_pair_list_copy },
1577 { "fr_pair_list_copy_by_da", test_fr_pair_list_copy_by_da },
1578 { "fr_pair_list_copy_by_ancestor", test_fr_pair_list_copy_by_ancestor },
1579 { "fr_pair_list_sort", test_fr_pair_list_sort },
1580
1581 /* Copy */
1582 { "fr_pair_value_copy", test_fr_pair_value_copy },
1583
1584
1585 /* parenting */
1586 { "test_fr_pair_nested_verify", test_fr_pair_nested_verify },
1587
1588 /* Strings */
1589 { "fr_pair_value_from_str", test_fr_pair_value_from_str },
1590 { "fr_pair_value_strdup", test_fr_pair_value_strdup },
1591 { "fr_pair_value_strdup_shallow", test_fr_pair_value_strdup_shallow },
1592 { "fr_pair_value_strtrim", test_fr_pair_value_strtrim },
1593 { "fr_pair_value_aprintf", test_fr_pair_value_aprintf },
1594
1595 /* Assign and manipulate binary-safe strings */
1596 { "fr_pair_value_bstr_alloc", test_fr_pair_value_bstr_alloc },
1597 { "fr_pair_value_bstr_realloc", test_fr_pair_value_bstr_realloc },
1598 { "fr_pair_value_bstrndup", test_fr_pair_value_bstrndup },
1599 { "fr_pair_value_bstrdup_buffer", test_fr_pair_value_bstrdup_buffer },
1600 { "fr_pair_value_bstrndup_shallow", test_fr_pair_value_bstrndup_shallow },
1601 { "fr_pair_value_bstrdup_buffer_shallow", test_fr_pair_value_bstrdup_buffer_shallow },
1602
1603 /* Assign and manipulate octets strings */
1604 { "fr_pair_value_mem_alloc", test_fr_pair_value_mem_alloc },
1605 { "fr_pair_value_mem_realloc", test_fr_pair_value_mem_realloc },
1606 { "fr_pair_value_memdup", test_fr_pair_value_memdup },
1607 { "fr_pair_value_memdup_buffer", test_fr_pair_value_memdup_buffer },
1608 { "fr_pair_value_memdup_shallow", test_fr_pair_value_memdup_shallow },
1609 { "fr_pair_value_memdup_buffer_shallow", test_fr_pair_value_memdup_buffer_shallow },
1610
1611 /* Enum functions */
1612 { "fr_pair_value_enum", test_fr_pair_value_enum },
1613 { "fr_pair_value_enum_box", test_fr_pair_value_enum_box },
1614
1616};
static int const char char buffer[256]
Definition acutest.h:641
#define TEST_CHECK(cond)
Definition acutest.h:101
#define TEST_CHECK_(cond,...)
Definition acutest.h:99
#define TEST_CASE(name)
Definition acutest.h:203
#define TEST_ASSERT(cond)
Definition acutest.h:125
#define TEST_TERMINATOR
Definition acutest.h:77
#define TEST_MSG(...)
Definition acutest.h:234
Common initialisation for acutest binaries.
#define NUM_ELEMENTS(_t)
Definition build.h:437
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:5326
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2717
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:2818
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
talloc_free(hp)
#define fr_time()
Definition event.c:58
@ 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:2927
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:1416
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:3027
int fr_pair_value_aprintf(fr_pair_t *vp, char const *fmt,...)
Print data into an "string" data type.
Definition pair.c:2662
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:1665
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:2303
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:2897
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:782
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:2027
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition pair.c:2598
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:2818
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:2552
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:707
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:872
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:1949
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:2798
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:1297
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:1641
fr_cmp_ret_t fr_pair_cmp_by_da(void const *a, void const *b)
Order attributes by their da.
Definition pair.c:1796
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:754
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:284
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:1547
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:2435
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:2871
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:2994
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:2747
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:2694
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:2719
void fr_pair_value_clear(fr_pair_t *vp)
Free/zero out value (or children) of a given VP.
Definition pair.c:2485
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:1778
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:1473
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:1760
int fr_pair_value_copy(fr_pair_t *dst, fr_pair_t *src)
Copy the value from one pair to another.
Definition pair.c:2515
int fr_pair_steal(TALLOC_CTX *ctx, fr_pair_t *vp)
Steal one VP.
Definition pair.c:534
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:2952
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition pair.c:500
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:2846
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:2641
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:477
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:1266
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:1203
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:2391
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:609
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:2972
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:2622
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:1443
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:381
static void test_fr_pair_value_memdup_shallow(void)
static void test_fr_pair_print_secure(void)
static void test_fr_pair_list_copy_by_ancestor(void)
static void test_fr_dict_by_protocol_substr_no_overflow(void)
static void test_fr_pair_afrom_child_num(void)
static void test_fr_pair_value_aprintf(void)
static void test_fr_pair_value_mem_realloc(void)
static TALLOC_CTX * autofree
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)
static void test_fr_pair_delete(void)
static void test_fr_pair_list_cmp(void)
static void test_fr_pair_print(void)
static void test_fr_pair_copy(void)
static void test_fr_pair_afrom_da(void)
static void test_fr_pair_value_mem_alloc(void)
static void test_fr_pair_value_bstrndup(void)
static void test_fr_pair_find_by_child_num_idx(void)
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)
static void test_fr_pair_value_memdup_buffer_shallow(void)
static void test_fr_pair_value_bstr_realloc(void)
static fr_pair_list_t test_pairs
static void test_fr_pair_dcursor_by_da_init(void)
static void test_fr_pair_print_name(void)
static void test_fr_pair_delete_by_da(void)
static void test_fr_pair_append(void)
static fr_dict_t * test_dict
static void test_fr_pair_value_strdup_shallow(void)
static void test_fr_pair_find_by_da_idx(void)
static void test_fr_pair_nested_verify(void)
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)
static void test_fr_pair_value_enum(void)
static void test_fr_pair_value_bstr_alloc(void)
static void test_fr_pair_list_sort(void)
static void test_fr_pair_value_strdup(void)
static void test_fr_pair_cmp(void)
static void test_fr_pair_list_print(void)
static void test_fr_pair_prepend_by_da(void)
static void test_fr_pair_afrom_da_nested(void)
static void test_fr_pair_list_copy_by_da(void)
static void test_fr_pair_value_from_str(void)
static void test_fr_pair_append_by_da_parent(void)
static void test_fr_pair_steal(void)
static void test_fr_pair_delete_by_child_num(void)
static void test_fr_pair_dcursor_by_ancestor_init(void)
static void test_fr_pair_delete_by_da_nested(void)
static void test_init(void)
Global initialisation.
static void test_fr_pair_raw_afrom_pair(void)
static void test_fr_pair_update_by_da_parent(void)
static void test_fr_pair_find_by_da_nested(void)
static void test_fr_pair_dcursor_value_init(void)
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:1561
static void test_fr_pair_debug(void)
fr_pair_debug() and fr_pair_list_debug() write to a FILE, not to an sbuff
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
#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
return count
Definition module.c:155
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
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:640
#define PAIR_VERIFY(_x)
Definition pair.h:209
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:285
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:605
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:658
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:864
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:7577
fr_sbuff_unescape_rules_t const fr_value_unescape_double
Definition value.c:282
static fr_sbuff_err_t char ** out
Definition value.h:1061