The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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.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
417 TEST_CASE("Look for child in first node after second");
418 TEST_CHECK_PAIR(vp_found, NULL);
419
420 /*
421 * Add third nested TLV with child of same type as first
422 */
426 fr_pair_append(&vp3->vp_group, vp4);
428 fr_pair_append(&vp4->vp_group, vp3);
429
430 /*
431 * Repeat search 3 times to find both instances and then NULL
432 */
434 TEST_CASE("Find child node in first TLV");
435 TEST_CHECK_PAIR(vp_found, vp1);
436
438 TEST_CASE("Find child node in third TLV");
439 TEST_CHECK_PAIR(vp_found, vp3);
440
442 TEST_CASE("Find child node after third TLV");
443 TEST_CHECK_PAIR(vp_found, NULL);
444
445 /*
446 * Add some "flat list" attributes
447 */
452
453 /*
454 * Repeat search 5 times to find all instances and then NULL
455 * fr_pair_find_by_da_nested searches nested first then flat
456 */
458 TEST_CASE("Find child node in first TLV");
459 TEST_CHECK_PAIR(vp_found, vp1);
460
462 TEST_CASE("Find child node in third TLV");
463 TEST_CHECK_PAIR(vp_found, vp3);
464
466 TEST_CASE("Find first entry in \"flat\" list");
467 TEST_CHECK_PAIR(vp_found, vp4);
468
470 TEST_CASE("Find second \"flat\" list entry");
471 TEST_CHECK_PAIR(vp_found, vp5);
472
474 TEST_CASE("Find NULL at end of list");
475 TEST_CHECK_PAIR(vp_found, NULL);
476
478}
479
480static void test_fr_pair_append(void)
481{
482 fr_dcursor_t cursor;
483 fr_pair_t *vp;
485 size_t count = 0;
486
487 TEST_CASE("Add 3 pairs using fr_pair_append()");
488
490
497
498 /* lets' count */
499 for (vp = fr_pair_dcursor_init(&cursor, &local_pairs);
500 vp;
501 vp = fr_dcursor_next(&cursor)) count++;
502
503 TEST_CASE("Expected (count == 3)");
504 TEST_CHECK(count == 3);
505
507}
508
510{
511 fr_pair_t *leaf1, *leaf2, *found, *inter1, *inter2;
513 int ret;
514
516
517 TEST_CASE("Add nested attribute including parents");
519 TEST_CHECK(ret == 0);
520 TEST_CHECK(leaf1 != NULL);
521
522 TEST_CASE("Check nested attributes added");
524 TEST_ASSERT(found != NULL);
525 inter1 = found;
526 found = fr_pair_find_by_da(&inter1->vp_group, NULL, fr_dict_attr_test_nested_child_tlv);
527 TEST_ASSERT(found != NULL);
528 inter2 = found;
529 found = fr_pair_find_by_da(&inter2->vp_group, NULL, fr_dict_attr_test_nested_leaf_int32);
530 TEST_CHECK_PAIR(found, leaf1);
531
532 TEST_CASE("Ensure no flat list attribute created");
534 TEST_CHECK_PAIR(found, NULL);
535
536 TEST_CASE("Add additional nested attribute where parents exist");
538 TEST_CHECK(ret == 0);
539 TEST_CHECK(leaf2 != NULL);
540 TEST_CHECK(leaf2 != leaf1);
541
542 TEST_CASE("Check additional leaf added under existing parent");
543 found = fr_pair_find_by_da(&inter2->vp_group, NULL, fr_dict_attr_test_nested_leaf_string);
544 TEST_CHECK_PAIR(found, leaf2);
545
546 TEST_CASE("Check no extra parent attributes created");
548 TEST_CHECK_PAIR(found, inter1);
550 TEST_CHECK_PAIR(found, NULL);
551
552 found = fr_pair_find_by_da(&inter1->vp_group, NULL, fr_dict_attr_test_nested_child_tlv);
553 TEST_CHECK_PAIR(found, inter2);
554 found = fr_pair_find_by_da(&inter1->vp_group, inter2, fr_dict_attr_test_nested_child_tlv);
555 TEST_CHECK_PAIR(found, NULL);
556
558}
559
561{
562 TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete_by_child_num()");
564
565 TEST_CASE("The fr_dict_attr_test_string shouldn't exist in 'test_pairs'");
567
568 TEST_CASE("Add fr_dict_attr_test_string back into 'test_pairs'");
570}
571
573{
574 fr_dcursor_t cursor;
575 fr_pair_t *vp;
577 TALLOC_CTX *ctx = talloc_null_ctx();
578
580
581 TEST_CASE("Add using fr_pair_prepend_by_da()");
583
584 /* lets' count */
585 for (vp = fr_pair_dcursor_init(&cursor, &local_pairs);
586 vp;
587 vp = fr_dcursor_next(&cursor)) {
588 TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
590 }
591
593}
594
596{
597 fr_pair_t *vp, *group;
598
600 if (!group) return; /* quiet clang scan */
601
602 TEST_CASE("Update Add using fr_pair_prepend_by_da()");
603 TEST_CHECK(fr_pair_update_by_da_parent(group, &vp, fr_dict_attr_test_uint32) == 0); /* attribute doesn't exist in this group */
604 vp->vp_uint32 = 54321;
605
606 TEST_CASE("Expected fr_dict_attr_test_uint32 (vp->vp_uint32 == 54321)");
607 TEST_CHECK((vp = fr_pair_find_by_da(&group->vp_group, NULL, fr_dict_attr_test_uint32)) != NULL);
608
609 TEST_CASE("Validating PAIR_VERIFY()");
611
612 TEST_CASE("Expected (vp == 54321)");
613 TEST_CHECK(vp && vp->vp_uint32 == 54321);
614
615 talloc_free(group);
616}
617
619{
620 TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete_by_da()");
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_delete(void)
631{
632 fr_pair_t *vp;
633
634 TEST_CASE("Delete fr_dict_attr_test_string using fr_pair_delete()");
637
638 TEST_CASE("The fr_dict_attr_test_string shouldn't exist in 'test_pairs'");
640
641 TEST_CASE("Add fr_dict_attr_test_string back into 'test_pairs'");
643}
644
645static void test_fr_pair_cmp(void)
646{
647 fr_pair_t *vp1, *vp2;
648
649 TEST_CASE("Create the vp1 'Test-Integer = 123'");
651
652 TEST_CASE("Validating PAIR_VERIFY()");
653 PAIR_VERIFY(vp1);
654
655 vp1->op = T_OP_EQ;
656 vp1->vp_uint32 = 123;
657
658 TEST_CASE("Create the vp2 'Test-Integer = 321'");
660
661 TEST_CASE("Validating PAIR_VERIFY()");
662 PAIR_VERIFY(vp2);
663
664 vp2->op = T_OP_CMP_EQ;
665 vp2->vp_uint32 = 321;
666
667 TEST_CASE("Compare fr_pair_cmp(vp1 == vp2) should be FALSE");
668 TEST_CHECK(fr_pair_cmp(vp1, vp2) == 0);
669}
670
671static void test_fr_pair_list_cmp(void)
672{
673 fr_pair_list_t local_pairs1, local_pairs2;
674
675 fr_pair_list_init(&local_pairs1);
676 fr_pair_list_init(&local_pairs2);
677
678 TEST_CASE("Create 'local_pairs1'");
679 TEST_CHECK(fr_pair_test_list_alloc(autofree, &local_pairs1, NULL) == 0);
680
681 TEST_CASE("Create 'local_pairs2'");
682 TEST_CHECK(fr_pair_test_list_alloc(autofree, &local_pairs2, NULL) == 0);
683
684 TEST_CASE("Check if 'local_pairs1' == 'local_pairs2' using fr_pair_list_cmp()");
685 TEST_CHECK(fr_pair_list_cmp(&local_pairs1, &local_pairs2) == 0);
686
687 fr_pair_list_free(&local_pairs1);
688 fr_pair_list_free(&local_pairs2);
689}
690
691static void test_fr_pair_list_copy(void)
692{
694
696
697 TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
699
700 TEST_CASE("Check if 'local_pairs' == 'test_pairs' using fr_pair_list_cmp()");
702
704}
705
707{
708 fr_dcursor_t cursor;
709 fr_pair_t *vp;
711
713
714 TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
716
717 TEST_CASE("The 'local_pairs' should have only fr_dict_attr_test_string");
718 for (vp = fr_pair_dcursor_init(&cursor, &local_pairs);
719 vp;
720 vp = fr_dcursor_next(&cursor)) {
721 TEST_CASE("Validating PAIR_VERIFY()");
723
724 TEST_CASE("Expected (vp->da == fr_dict_attr_test_string)");
726 }
727
729}
730
732{
733 fr_pair_t *vp;
735
737
738 TEST_CASE("Copy 'test_pairs' into 'local_pairs'");
740
741 TEST_CASE("The 'local_pairs' should have only one attribute in it");
743
744 TEST_CASE("The 'local_pairs' should have only fr_dict_attr_test_tlv_string (ancestor of 'Test-TLV-Root'");
746
747 TEST_CASE("Validating we copied the attribute");
748 TEST_CHECK(vp != NULL);
749 if (!vp) return;
750
751#ifdef TEST_NESTED_PAIRS
752 TEST_CASE("Expected copied attribute == fr_dict_attr_test_tlv)");
754#else
755 TEST_CASE("Expected copied attribute == fr_dict_attr_test_tlv_string)");
757#endif
758
759 TEST_CASE("Verifying the copied attribute");
761
762 TEST_CASE("Expecting nothing else in local list");
764
766}
767
768static void test_fr_pair_list_sort(void)
769{
770 fr_dcursor_t cursor;
771 fr_pair_t *vp;
773 TALLOC_CTX *ctx = talloc_null_ctx();
774
775 TEST_CASE("Create 'local_pairs' with 3 attributes not ordered");
777
778 TEST_CASE("Add fr_dict_attr_test_string back into 'local_pairs'");
783 TEST_CHECK(fr_pair_prepend_by_da(ctx, NULL, &local_pairs, fr_dict_attr_test_enum) == 0); // It will be go to the tail
785
786 /*
787 * FIXME - This test doesn't check for intra-type stability
788 */
789 TEST_CASE("Sorting 'local_pairs' by fr_pair_list_sort(local_pairs, fr_pair_cmp_by_da)");
791
792 TEST_CASE("1st (da == fr_dict_attr_test_string)");
793 TEST_CHECK((vp = fr_pair_dcursor_init(&cursor, &local_pairs)) != NULL);
795
796 TEST_CASE("2nd (da == fr_dict_attr_test_octets)");
797 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
799
800 TEST_CASE("3rd (da == fr_dict_attr_test_ipv4_addr)");
801 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
803
804 TEST_CASE("4th (da == fr_dict_attr_test_uint32)");
805 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
807
808 TEST_CASE("5th (da == fr_dict_attr_test_date)");
809 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
811
812 TEST_CASE("6th (da == fr_dict_attr_test_enum)");
813 TEST_CHECK((vp = fr_dcursor_next(&cursor)) != NULL);
815
817}
818
819static void test_fr_pair_value_copy(void)
820{
821 fr_pair_t *vp1, *vp2;
822
823 TEST_CASE("Create 'vp1' with Test-Integer = 123");
825 vp1->vp_uint32 = 123;
826
827 TEST_CASE("Validating PAIR_VERIFY()");
828 PAIR_VERIFY(vp1);
829
830 TEST_CASE("Create 'vp2'");
832
833 TEST_CASE("Validating PAIR_VERIFY()");
834 PAIR_VERIFY(vp2);
835
836 TEST_CASE("Copy 'vp1' to 'vp2' using fr_pair_value_copy()");
837 TEST_CHECK(fr_pair_value_copy(vp2, vp1) == 0);
838
839 TEST_CASE("Validating PAIR_VERIFY()");
840 PAIR_VERIFY(vp2);
841
842 TEST_CASE("Check (vp1 == vp2)");
843 TEST_CHECK(vp2->vp_uint32 == 123);
844}
845
847{
848 fr_pair_t *vp;
849
850 TEST_CASE("Find 'Test-String'");
852
853 TEST_CASE("Validating PAIR_VERIFY()");
855
856 TEST_CASE("Convert 'test_string' value to attribute value using fr_pair_value_from_str()");
858
859 TEST_CASE("Validating PAIR_VERIFY()");
861
862 TEST_CASE("Check (vp->vp_string == test_string)");
863 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
864}
865
867{
868 fr_pair_t *vp;
869
870 TEST_CASE("Find 'Test-String'");
872
873 TEST_CASE("Validating PAIR_VERIFY()");
875
876 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup()");
878
879 TEST_CASE("Validating PAIR_VERIFY()");
881
882 TEST_CASE("Check (vp->vp_string == test_string)");
883 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
884}
885
887{
888 fr_pair_t *vp, *nvp;
889 char *copy_test_string;
890
891 TEST_CASE("Find 'Test-String'");
893
894 TEST_CASE("Validating PAIR_VERIFY()");
896
897 MEM(nvp = fr_pair_copy(NULL, vp));
898
899 copy_test_string = talloc_strdup(nvp, test_string);
900 talloc_set_type(copy_test_string, char);
901
902 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup_shallow()");
903 TEST_CHECK(fr_pair_value_strdup_shallow(nvp, copy_test_string, true) == 0);
904
905 TEST_CASE("Validating PAIR_VERIFY()");
906 PAIR_VERIFY(nvp);
907
908 TEST_CASE("Check (vp->vp_string == copy_test_string)");
909 TEST_CHECK(nvp && strncmp(nvp->vp_strvalue, test_string, strlen(copy_test_string)) == 0);
910
911 talloc_free(nvp);
912}
913
915{
916 fr_pair_t *vp;
917
918 TEST_CASE("Find 'Test-String'");
920
921 TEST_CASE("Validating PAIR_VERIFY()");
923
924 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_strdup_shallow()");
926
927 TEST_CASE("Trim the length of the string buffer using fr_pair_value_strtrim()");
929
930 TEST_CASE("Validating PAIR_VERIFY()");
932
933 TEST_CASE("Check (vp->vp_string == test_string)");
934 TEST_CHECK(vp && strcmp(vp->vp_strvalue, test_string) == 0);
935}
936
938{
939 fr_pair_t *vp;
940 char fmt_test[64];
941 fr_time_t now = fr_time();
942
943 snprintf(fmt_test, sizeof(fmt_test), "Now is %"PRId64, fr_time_unwrap(now));
944
945 TEST_CASE("Find 'Test-String'");
947
948 TEST_CASE("Validating PAIR_VERIFY()");
950
951 TEST_CASE("Copy content of 'fmt_test' to attribute value using fr_pair_value_aprintf()");
952 TEST_CHECK(fr_pair_value_aprintf(vp, "Now is %"PRId64, fr_time_unwrap(now)) == 0);
953
954 TEST_CASE("Validating PAIR_VERIFY()");
956
957 TEST_CASE("Check (vp->vp_string == fmt_test)");
958 TEST_CHECK(vp && strcmp(vp->vp_strvalue, fmt_test) == 0);
959}
960
962{
963 fr_pair_t *vp;
964 char *out = NULL;
965
966 TEST_CASE("Find 'Test-String'");
968
969 TEST_CASE("Validating PAIR_VERIFY()");
971
972 TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
974
975 TEST_CASE("Validating PAIR_VERIFY()");
977
978 TEST_CASE("Copy 'test_string' to the pre-allocated pointer");
980
981 TEST_CASE("Check (out == test_string)");
982 TEST_CHECK(memcmp(out, test_string, test_string_len-1) == 0);
983
984 TEST_CASE("Check (vp->vp_string == test_string)");
985 TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
986}
987
989{
990 fr_pair_t *vp;
991 char *out = NULL;
992
993 TEST_CASE("Find 'Test-String'");
995
996 TEST_CASE("Validating PAIR_VERIFY()");
998
999 TEST_CASE("Pre-allocate 1 byte of memory buffer using fr_pair_value_bstr_alloc()");
1000 TEST_CHECK(fr_pair_value_bstr_alloc(vp, &out, 1, false) == 0);
1001
1002 TEST_CASE("Re-allocate (test_string_len-1) byte of memory buffer using fr_pair_value_bstr_realloc()");
1004
1005 TEST_CASE("Validating PAIR_VERIFY()");
1006 PAIR_VERIFY(vp);
1007
1008 TEST_CASE("Copy 'test_string' to the pre-allocated pointer");
1010
1011 TEST_CASE("Check (out == test_string)");
1012 TEST_CHECK(memcmp(out, test_string, test_string_len-1) == 0);
1013
1014 TEST_CASE("Check (vp->vp_string == test_string)");
1015 TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
1016}
1017
1019{
1020 fr_pair_t *vp;
1021
1022 TEST_CASE("Find 'Test-String'");
1024
1025 TEST_CASE("Validating PAIR_VERIFY()");
1026 PAIR_VERIFY(vp);
1027
1028 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrndup()");
1030
1031 TEST_CASE("Check (vp->vp_string == test_string)");
1032 TEST_CHECK(vp && memcmp(vp->vp_strvalue, test_string, test_string_len-1) == 0);
1033}
1034
1036{
1037 fr_pair_t *vp;
1038 char *copy_test_string;
1039
1040 TEST_CASE("Find 'Test-String'");
1042
1043 TEST_CASE("Validating PAIR_VERIFY()");
1044 PAIR_VERIFY(vp);
1045
1046 copy_test_string = talloc_strdup(vp, test_string);
1047 talloc_set_type(copy_test_string, char);
1048
1049 TEST_CASE("Copy content of 'copy_test_string' to attribute value using fr_pair_value_bstrdup_buffer()");
1050 TEST_CHECK(fr_pair_value_bstrdup_buffer(vp, copy_test_string, false) == 0);
1051
1052 TEST_CASE("Check (vp->vp_string == test_string)");
1053 TEST_CHECK(vp && strcmp(vp->vp_strvalue, copy_test_string) == 0);
1054
1055 talloc_free(copy_test_string);
1056}
1057
1059{
1060 fr_pair_t *vp;
1061 char *copy_test_string;
1062
1063 TEST_CASE("Find 'Test-String'");
1065
1066 TEST_CASE("Validating PAIR_VERIFY()");
1067 PAIR_VERIFY(vp);
1068
1069 copy_test_string = talloc_strdup(vp, test_string);
1070 talloc_set_type(copy_test_string, char);
1071
1072 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrndup_shallow()");
1073 TEST_CHECK(fr_pair_value_bstrndup_shallow(vp, copy_test_string, strlen(copy_test_string), true) == 0);
1074
1075 TEST_CASE("Check (vp->vp_string == copy_test_string)");
1076 TEST_CHECK(vp && strncmp(vp->vp_strvalue, test_string, test_string_len) == 0);
1077
1078 talloc_free(copy_test_string);
1079}
1080
1082{
1083 fr_pair_t *vp;
1084 char *copy_test_string;
1085
1086 TEST_CASE("Find 'Test-String'");
1088
1089 TEST_CASE("Validating PAIR_VERIFY()");
1090 PAIR_VERIFY(vp);
1091
1092 copy_test_string = talloc_strdup(vp, test_string);
1093 talloc_set_type(copy_test_string, char);
1094
1095 TEST_CASE("Copy content of 'test_string' to attribute value using fr_pair_value_bstrdup_buffer_shallow()");
1096 TEST_CHECK(fr_pair_value_bstrdup_buffer_shallow(vp, copy_test_string, true) == 0);
1097
1098 TEST_CASE("Check (vp->vp_string == copy_test_string)");
1099 TEST_CHECK(vp && strncmp(vp->vp_strvalue, test_string, test_string_len) == 0);
1100
1101 talloc_free(copy_test_string);
1102}
1103
1105{
1106 fr_pair_t *vp;
1107 uint8_t *out;
1108
1109 TEST_CASE("Find 'Test-Octets'");
1111
1112 TEST_CASE("Validating PAIR_VERIFY()");
1113 PAIR_VERIFY(vp);
1114
1115 TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
1117
1118 TEST_CASE("Copy 'test_octets' to the pre-allocated pointer");
1120
1121 TEST_CASE("Check (out == test_octets)");
1123
1124 TEST_CASE("Check (vp->vp_octets == test_octets)");
1125 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1126}
1127
1129{
1130 fr_pair_t *vp;
1131 uint8_t *out;
1132
1133 TEST_CASE("Find 'Test-Octets'");
1135
1136 TEST_CASE("Validating PAIR_VERIFY()");
1137 PAIR_VERIFY(vp);
1138
1139 TEST_CASE("Pre-allocate a memory buffer using fr_pair_value_bstr_alloc()");
1141
1142 TEST_CASE("Copy 'test_octets' to the pre-allocated pointer");
1144
1145 TEST_CASE("Realloc pre-allocated pointer to fit extra 'test_octets' copy");
1147
1148 TEST_CASE("Copy 'test_octets' into the tail");
1150
1151 TEST_CASE("Check first chunk (out == test_octets)");
1153
1154 TEST_CHECK(vp != NULL);
1155
1156 TEST_CASE("Check first chunk (vp->vp_octets == test_octets)");
1157 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1158
1159 TEST_CASE("Check second chunk (out+NUM_ELEMENTS(test_octets) == test_octets)");
1161
1162 TEST_CASE("Check second chunk (vp->vp_octets+NUM_ELEMENTS(test_octets) == test_octets)");
1164}
1165
1167{
1168 fr_pair_t *vp;
1169
1170 TEST_CASE("Find 'Test-Octets'");
1172
1173 TEST_CASE("Validating PAIR_VERIFY()");
1174 PAIR_VERIFY(vp);
1175
1176 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup()");
1178
1179 TEST_CASE("Check (vp->vp_octets == test_octets)");
1180 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1181}
1182
1184{
1185 fr_pair_t *vp;
1186 uint8_t *copy_test_octets;
1187
1188 TEST_CASE("Find 'Test-Octets'");
1190
1191 TEST_CASE("Validating PAIR_VERIFY()");
1192 PAIR_VERIFY(vp);
1193
1194 copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1195 talloc_set_type(copy_test_octets, uint8_t);
1196
1197 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_buffer()");
1198 TEST_CHECK(fr_pair_value_memdup_buffer(vp, copy_test_octets, true) == 0);
1199
1200 TEST_CASE("Check (vp->vp_octets == test_octets)");
1201 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1202
1203 talloc_free(copy_test_octets);
1204}
1205
1207{
1208 fr_pair_t *vp;
1209 uint8_t *copy_test_octets;
1210
1211 TEST_CASE("Find 'Test-Octets'");
1213
1214 TEST_CASE("Validating PAIR_VERIFY()");
1215 PAIR_VERIFY(vp);
1216
1217 copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1218 talloc_set_type(copy_test_octets, uint8_t);
1219
1220 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_shallow()");
1221 TEST_CHECK(fr_pair_value_memdup_shallow(vp, copy_test_octets, NUM_ELEMENTS(test_octets), true) == 0);
1222
1223 TEST_CASE("Check (vp->vp_octets == test_octets)");
1224 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1225
1226 talloc_free(copy_test_octets);
1227}
1228
1230{
1231 fr_pair_t *vp;
1232 uint8_t *copy_test_octets;
1233
1234 TEST_CASE("Find 'Test-Octets'");
1236
1237 TEST_CASE("Validating PAIR_VERIFY()");
1238 PAIR_VERIFY(vp);
1239
1240 copy_test_octets = talloc_memdup(vp, test_octets, NUM_ELEMENTS(test_octets));
1241 talloc_set_type(copy_test_octets, uint8_t);
1242
1243 TEST_CASE("Copy content of 'test_octets' to attribute value using fr_pair_value_memdup_buffer_shallow()");
1244 TEST_CHECK(fr_pair_value_memdup_buffer_shallow(vp, copy_test_octets, true) == 0);
1245
1246 TEST_CASE("Check (vp->vp_octets == copy_test_octets)");
1247 TEST_CHECK(vp && memcmp(vp->vp_octets, test_octets, NUM_ELEMENTS(test_octets)) == 0);
1248
1249 talloc_free(copy_test_octets);
1250}
1251
1253{
1254 fr_pair_t *vp;
1255 char const *var;
1256 char buf[20];
1257
1258 TEST_CASE("Find 'Test-Values'");
1260
1261 TEST_CASE("Validating PAIR_VERIFY()");
1262 PAIR_VERIFY(vp);
1263
1264 vp->vp_uint32 = 123;
1265
1266 TEST_CASE("Lookup enum value attribute using fr_pair_value_enum()");
1267
1268 TEST_CHECK((var = fr_pair_value_enum(vp, buf)) != NULL);
1269 TEST_MSG("Checking fr_pair_value_enum()");
1270
1271 TEST_CHECK(var && strcmp(var, "test123") == 0);
1272 TEST_MSG("Expected var == 'test123'");
1273}
1274
1276{
1277 fr_pair_t *vp;
1278 fr_value_box_t const *vb;
1279
1280 TEST_CASE("Find 'Test-Values'");
1282
1283 TEST_CASE("Validating PAIR_VERIFY()");
1284 PAIR_VERIFY(vp);
1285
1286 vp->vp_uint32 = 123;
1287
1288 TEST_CASE("Lookup enum value attribute using fr_pair_value_enum_box()");
1289
1291 TEST_MSG("Checking fr_pair_value_enum()");
1292
1293 TEST_CHECK(vb->vb_uint32 == 123);
1294 TEST_MSG("Expected vb->vb_uint32 == 123");
1295}
1296
1297/*
1298 * Regression test: fr_dict_by_protocol_substr() used to dereference
1299 * our_name.p without a bounds check after fr_sbuff_out_bstrncpy_allowed()
1300 * had consumed every byte. If the input sbuff was bounded by length
1301 * (rather than a NUL sentinel), that read was one byte past in->end.
1302 *
1303 * The buggy code:
1304 * if (*(our_name.p) && (*(our_name.p) != '.')) { return 0 with dict_def; }
1305 *
1306 * With the bug, an OOB byte equal to '.' or NUL would let execution
1307 * fall through to the hash lookup; an OOB byte of any other value
1308 * would take the early-return path and yield slen=0. Either way,
1309 * the read past in->end is undefined.
1310 *
1311 * We construct a sbuff where in->end points one byte before a known
1312 * non-NUL, non-'.' sentinel. Then we run the function with
1313 * `fr_dict_test`, which has been added to the protocol table so the
1314 * hash lookup will succeed when the bounds check is honoured.
1315 *
1316 * Bug: reads buf[4]='X', early-returns 0 with *out = dict_def (NULL).
1317 * Fix: bounds check trips, hash lookup finds "test", returns slen=4
1318 * with *out = fr_dict_test.
1319 */
1320extern int dict_protocol_add(fr_dict_t *dict);
1321
1323{
1324 char buf[8];
1325 fr_sbuff_t sbuff;
1326 fr_dict_t const *out_dict = NULL;
1327 fr_slen_t slen;
1328
1329 if (dict_protocol_add(test_dict) < 0) {
1330 TEST_CHECK_(0, "dict_protocol_add failed: %s", fr_strerror());
1331 return;
1332 }
1333
1334 memcpy(buf, "testXXXX", 8); /* "test" then sentinel bytes the buggy code would read */
1335 fr_sbuff_init_in(&sbuff, buf, (size_t)4); /* Only "test" is visible */
1336
1337 slen = fr_dict_by_protocol_substr(NULL, &out_dict, &sbuff, NULL);
1338
1339 TEST_CHECK(slen == 4);
1340 TEST_MSG("Expected slen=4 (matched 'test' protocol), got %zd", (ssize_t)slen);
1341
1342 TEST_CHECK(out_dict == test_dict);
1343 TEST_MSG("Expected out_dict==test_dict; OOB read of sentinel byte made the buggy code early-return with dict_def (NULL)");
1344}
1345
1347 /*
1348 * Regression tests
1349 */
1350 { "fr_dict_by_protocol_substr no overflow", test_fr_dict_by_protocol_substr_no_overflow },
1351
1352 /*
1353 * Allocation and management
1354 */
1355 { "fr_pair_afrom_da", test_fr_pair_afrom_da },
1356 { "fr_pair_afrom_child_num", test_fr_pair_afrom_child_num },
1357 { "fr_pair_afrom_da_nested", test_fr_pair_afrom_da_nested },
1358 { "fr_pair_copy", test_fr_pair_copy },
1359 { "fr_pair_steal", test_fr_pair_steal },
1360
1361 /* Searching and list modification */
1362 { "fr_dcursor_iter_by_da_init", test_fr_pair_dcursor_by_da_init },
1363 { "fr_pair_dcursor_by_ancestor_init", test_fr_pair_dcursor_by_ancestor_init },
1364 { "fr_pair_dcursor_value_init", test_fr_pair_dcursor_value_init },
1365 { "fr_pair_raw_afrom_pair", test_fr_pair_raw_afrom_pair },
1366 { "fr_pair_find_by_da_idx", test_fr_pair_find_by_da_idx },
1367 { "fr_pair_find_by_child_num_idx", test_fr_pair_find_by_child_num_idx },
1368 { "fr_pair_find_by_da_nested", test_fr_pair_find_by_da_nested },
1369 { "fr_pair_append", test_fr_pair_append },
1370 { "fr_pair_prepend_by_da", test_fr_pair_prepend_by_da },
1371 { "fr_pair_append_by_da_parent", test_fr_pair_append_by_da_parent },
1372 { "fr_pair_delete_by_child_num", test_fr_pair_delete_by_child_num },
1373 { "fr_pair_update_by_da_parent", test_fr_pair_update_by_da_parent },
1374 { "fr_pair_delete", test_fr_pair_delete },
1375 { "fr_pair_delete_by_da", test_fr_pair_delete_by_da },
1376 { "fr_pair_delete_by_da_nested", test_fr_pair_delete_by_da_nested },
1377
1378 /* Compare */
1379 { "fr_pair_cmp", test_fr_pair_cmp },
1380 { "fr_pair_list_cmp", test_fr_pair_list_cmp },
1381
1382 /* Lists */
1383 { "fr_pair_list_copy", test_fr_pair_list_copy },
1384 { "fr_pair_list_copy_by_da", test_fr_pair_list_copy_by_da },
1385 { "fr_pair_list_copy_by_ancestor", test_fr_pair_list_copy_by_ancestor },
1386 { "fr_pair_list_sort", test_fr_pair_list_sort },
1387
1388 /* Copy */
1389 { "fr_pair_value_copy", test_fr_pair_value_copy },
1390
1391
1392 /* parenting */
1393 { "test_fr_pair_nested_verify", test_fr_pair_nested_verify },
1394
1395 /* Strings */
1396 { "fr_pair_value_from_str", test_fr_pair_value_from_str },
1397 { "fr_pair_value_strdup", test_fr_pair_value_strdup },
1398 { "fr_pair_value_strdup_shallow", test_fr_pair_value_strdup_shallow },
1399 { "fr_pair_value_strtrim", test_fr_pair_value_strtrim },
1400 { "fr_pair_value_aprintf", test_fr_pair_value_aprintf },
1401
1402 /* Assign and manipulate binary-safe strings */
1403 { "fr_pair_value_bstr_alloc", test_fr_pair_value_bstr_alloc },
1404 { "fr_pair_value_bstr_realloc", test_fr_pair_value_bstr_realloc },
1405 { "fr_pair_value_bstrndup", test_fr_pair_value_bstrndup },
1406 { "fr_pair_value_bstrdup_buffer", test_fr_pair_value_bstrdup_buffer },
1407 { "fr_pair_value_bstrndup_shallow", test_fr_pair_value_bstrndup_shallow },
1408 { "fr_pair_value_bstrdup_buffer_shallow", test_fr_pair_value_bstrdup_buffer_shallow },
1409
1410 /* Assign and manipulate octets strings */
1411 { "fr_pair_value_mem_alloc", test_fr_pair_value_mem_alloc },
1412 { "fr_pair_value_mem_realloc", test_fr_pair_value_mem_realloc },
1413 { "fr_pair_value_memdup", test_fr_pair_value_memdup },
1414 { "fr_pair_value_memdup_buffer", test_fr_pair_value_memdup_buffer },
1415 { "fr_pair_value_memdup_shallow", test_fr_pair_value_memdup_shallow },
1416 { "fr_pair_value_memdup_buffer_shallow", test_fr_pair_value_memdup_buffer_shallow },
1417
1418 /* Enum functions */
1419 { "fr_pair_value_enum", test_fr_pair_value_enum },
1420 { "fr_pair_value_enum_box", test_fr_pair_value_enum_box },
1421
1423};
#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
#define NUM_ELEMENTS(_t)
Definition build.h:358
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:36
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition debug.h:226
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:5166
fr_dict_attr_t const * fr_dict_root(fr_dict_t const *dict)
Return the root attribute of a dictionary.
Definition dict_util.c:2639
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:2739
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: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_list_copy_by_da(TALLOC_CTX *ctx, fr_pair_list_t *to, fr_pair_list_t const *from, fr_dict_attr_t const *da, unsigned int count)
Duplicate pairs in a list matching the specified da.
Definition pair.c:2416
int fr_pair_list_cmp(fr_pair_list_t const *a, fr_pair_list_t const *b)
Determine equality of two lists.
Definition pair.c:2054
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:2992
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:3092
int fr_pair_value_aprintf(fr_pair_t *vp, char const *fmt,...)
Print data into an "string" data type.
Definition pair.c:2727
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:1720
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:2326
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:2962
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, 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:784
int fr_pair_value_strdup(fr_pair_t *vp, char const *src, bool tainted)
Copy data into an "string" data type.
Definition pair.c:2663
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:2883
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:2617
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:907
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:1976
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:2863
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:1352
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:1696
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:290
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:1602
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:2465
void fr_pair_list_init(fr_pair_list_t *list)
Initialise a pair list header.
Definition pair.c:46
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:2936
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:3059
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:2812
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:2759
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:2784
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:1833
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:1528
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:1815
int fr_pair_value_copy(fr_pair_t *dst, fr_pair_t *src)
Copy the value from one pair to another.
Definition pair.c:2591
int fr_pair_steal(TALLOC_CTX *ctx, fr_pair_t *vp)
Steal one VP.
Definition pair.c:537
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:3017
fr_pair_t * fr_pair_copy(TALLOC_CTX *ctx, fr_pair_t const *vp)
Copy a single valuepair.
Definition pair.c:503
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:2911
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:2706
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:480
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:1321
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:1258
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
int8_t fr_pair_cmp_by_da(void const *a, void const *b)
Order attributes by their da, and tag.
Definition pair.c:1851
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:3037
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:2687
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:1498
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:384
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)
TEST_LIST
static void test_fr_pair_list_copy_by_ancestor(void)
Definition pair_tests.c:731
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:937
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:819
static void test_fr_pair_delete(void)
Definition pair_tests.c:630
static void test_fr_pair_list_cmp(void)
Definition pair_tests.c:671
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)
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_list_copy(void)
Definition pair_tests.c:691
static void test_fr_pair_value_memdup_buffer_shallow(void)
static void test_fr_pair_value_bstr_realloc(void)
Definition pair_tests.c:988
static void test_fr_pair_dcursor_by_da_init(void)
Definition pair_tests.c:250
static void test_fr_pair_delete_by_da(void)
Definition pair_tests.c:618
static void test_fr_pair_append(void)
Definition pair_tests.c:480
static void test_fr_pair_value_strdup_shallow(void)
Definition pair_tests.c:886
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_value_strtrim(void)
Definition pair_tests.c:914
static void test_fr_pair_value_enum(void)
static void test_fr_pair_value_bstr_alloc(void)
Definition pair_tests.c:961
static void test_fr_pair_list_sort(void)
Definition pair_tests.c:768
static void test_fr_pair_value_strdup(void)
Definition pair_tests.c:866
static void test_fr_pair_cmp(void)
Definition pair_tests.c:645
static void test_fr_pair_prepend_by_da(void)
Definition pair_tests.c:572
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:706
static void test_fr_pair_value_from_str(void)
Definition pair_tests.c:846
static void test_fr_pair_append_by_da_parent(void)
Definition pair_tests.c:509
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:560
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:595
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:1487
#define local_pairs
Convenience macro for accessing the state list.
Definition request.h:162
#define fr_sbuff_init_in(_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_OP_EQ
Definition token.h:81
@ T_OP_CMP_EQ
Definition token.h:104
#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:639
#define PAIR_VERIFY(_x)
Definition pair.h:204
void 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.
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
void fr_pair_list_free(fr_pair_list_t *list)
Free memory used by a valuepair list.
#define fr_pair_dcursor_init(_cursor, _list)
Initialises a special dcursor with callbacks that will maintain the attr sublists correctly.
Definition pair.h:604
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:657
size_t fr_pair_list_num_elements(fr_pair_list_t const *list)
Get the length of a list of fr_pair_t.
static fr_slen_t parent
Definition pair.h:858
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
fr_sbuff_unescape_rules_t const fr_value_unescape_double
Definition value.c:271
static size_t char ** out
Definition value.h:1030