The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
value_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 value box functions
18 *
19 * @file src/lib/util/test/value_tests.c
20 * @copyright 2026 Network RADIUS SAS (legal@networkradius.com)
21 */
22
23#include "acutest_common_init.h"
24#include "acutest_helpers.h"
25
26#include <freeradius-devel/util/value.h>
27
28static TALLOC_CTX *autofree;
29
30static void test_init(void) __attribute__((constructor));
31static void test_init(void)
32{
34 if (!autofree) {
35 fr_perror("value_tests");
36 fr_exit_now(EXIT_FAILURE);
37 }
38
40 fr_perror("value_tests");
41 fr_exit_now(EXIT_FAILURE);
42 }
43}
44
45/*
46 * Comparison tests (fr_value_box_cmp)
47 */
48static void test_cmp_uint32_equal(void)
49{
50 fr_value_box_t a, b;
51
52 fr_value_box(&a, (uint32_t) 42, false);
53 fr_value_box(&b, (uint32_t) 42, false);
54
55 TEST_CHECK(fr_value_box_cmp(&a, &b) == 0);
56}
57
58static void test_cmp_uint32_less(void)
59{
60 fr_value_box_t a, b;
61
62 fr_value_box(&a, (uint32_t) 10, false);
63 fr_value_box(&b, (uint32_t) 20, false);
64
65 TEST_CHECK(fr_value_box_cmp(&a, &b) == -1);
66 TEST_CHECK(fr_value_box_cmp(&b, &a) == 1);
67}
68
69static void test_cmp_int32(void)
70{
71 fr_value_box_t a, b;
72
73 fr_value_box(&a, (int32_t) -10, false);
74 fr_value_box(&b, (int32_t) 10, false);
75
76 TEST_CHECK(fr_value_box_cmp(&a, &b) == -1);
77 TEST_CHECK(fr_value_box_cmp(&b, &a) == 1);
78
79 fr_value_box(&b, (int32_t) -10, false);
80 TEST_CHECK(fr_value_box_cmp(&a, &b) == 0);
81}
82
83static void test_cmp_float64(void)
84{
85 fr_value_box_t a, b;
86
87 fr_value_box(&a, (double) 3.14, false);
88 fr_value_box(&b, (double) 2.71, false);
89
90 TEST_CHECK(fr_value_box_cmp(&a, &b) == 1);
91 TEST_CHECK(fr_value_box_cmp(&b, &a) == -1);
92
93 fr_value_box(&b, (double) 3.14, false);
94 TEST_CHECK(fr_value_box_cmp(&a, &b) == 0);
95}
96
97static void test_cmp_string(void)
98{
99 fr_value_box_t a, b;
100
101 fr_value_box_strdup(autofree, &a, NULL, "apple", false);
102 fr_value_box_strdup(autofree, &b, NULL, "banana", false);
103
104 TEST_CHECK(fr_value_box_cmp(&a, &b) == -1);
105 TEST_CHECK(fr_value_box_cmp(&b, &a) == 1);
106
108 fr_value_box_strdup(autofree, &b, NULL, "apple", false);
109 TEST_CHECK(fr_value_box_cmp(&a, &b) == 0);
110
113}
114
115static void test_cmp_octets(void)
116{
117 fr_value_box_t a, b;
118
119 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\x01\x02", 2, false);
120 fr_value_box_memdup(autofree, &b, NULL, (uint8_t const *)"\x01\x03", 2, false);
121
122 TEST_CHECK(fr_value_box_cmp(&a, &b) == -1);
123 TEST_CHECK(fr_value_box_cmp(&b, &a) == 1);
124
127}
128
129static void test_cmp_octets_length(void)
130{
131 fr_value_box_t a, b;
132
133 /* Same prefix but different length: shorter is "less" */
134 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\x01", 1, false);
135 fr_value_box_memdup(autofree, &b, NULL, (uint8_t const *)"\x01\x02", 2, false);
136
137 TEST_CHECK(fr_value_box_cmp(&a, &b) == -1);
138 TEST_CHECK(fr_value_box_cmp(&b, &a) == 1);
139
142}
143
144static void test_cmp_bool(void)
145{
146 fr_value_box_t a, b;
147
148 fr_value_box(&a, (bool) true, false);
149 fr_value_box(&b, (bool) false, false);
150
151 TEST_CHECK(fr_value_box_cmp(&a, &b) == 1);
152 TEST_CHECK(fr_value_box_cmp(&b, &a) == -1);
153
154 fr_value_box(&b, (bool) true, false);
155 TEST_CHECK(fr_value_box_cmp(&a, &b) == 0);
156}
157
159{
160 fr_value_box_t a, b;
161
162 fr_value_box(&a, (uint32_t) 42, false);
163 fr_value_box(&b, (uint64_t) 42, false);
164
165 /* Different types are incomparable, both directions return CMP_ERR exactly */
168}
169
170/*
171 * Comparison operator tests (fr_value_box_cmp_op)
172 */
173static void test_cmp_op_eq(void)
174{
175 fr_value_box_t a, b;
176
177 fr_value_box(&a, (uint32_t) 42, false);
178 fr_value_box(&b, (uint32_t) 42, false);
179
181
182 fr_value_box(&b, (uint32_t) 43, false);
184}
185
186static void test_cmp_op_ne(void)
187{
188 fr_value_box_t a, b;
189
190 fr_value_box(&a, (uint32_t) 42, false);
191 fr_value_box(&b, (uint32_t) 43, false);
192
194
195 fr_value_box(&b, (uint32_t) 42, false);
197}
198
199static void test_cmp_op_lt(void)
200{
201 fr_value_box_t a, b;
202
203 fr_value_box(&a, (uint32_t) 10, false);
204 fr_value_box(&b, (uint32_t) 20, false);
205
209}
210
211static void test_cmp_op_gt(void)
212{
213 fr_value_box_t a, b;
214
215 fr_value_box(&a, (uint32_t) 20, false);
216 fr_value_box(&b, (uint32_t) 10, false);
217
220}
221
222static void test_cmp_op_le(void)
223{
224 fr_value_box_t a, b;
225
226 fr_value_box(&a, (uint32_t) 10, false);
227 fr_value_box(&b, (uint32_t) 20, false);
228
231
232 fr_value_box(&b, (uint32_t) 10, false);
234}
235
236static void test_cmp_op_ge(void)
237{
238 fr_value_box_t a, b;
239
240 fr_value_box(&a, (uint32_t) 20, false);
241 fr_value_box(&b, (uint32_t) 10, false);
242
245
246 fr_value_box(&b, (uint32_t) 20, false);
248}
249
250/*
251 * Cast tests (fr_value_box_cast)
252 */
254{
255 fr_value_box_t src, dst;
256
257 fr_value_box(&src, (uint32_t) 42, false);
259
260 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT64, NULL, &src) == 0);
261 TEST_CHECK(dst.type == FR_TYPE_UINT64);
262 TEST_CHECK(dst.vb_uint64 == 42);
263}
264
266{
267 fr_value_box_t src, dst;
268
269 fr_value_box(&src, (uint32_t) 12345, false);
271
272 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_STRING, NULL, &src) == 0);
273 TEST_CHECK(dst.type == FR_TYPE_STRING);
274 TEST_CHECK_STRCMP(dst.vb_strvalue, "12345");
275
276 fr_value_box_clear(&dst);
277}
278
280{
281 fr_value_box_t src, dst;
282
283 fr_value_box_strdup(autofree, &src, NULL, "12345", false);
285
286 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT32, NULL, &src) >= 0);
287 TEST_CHECK(dst.type == FR_TYPE_UINT32);
288 TEST_CHECK(dst.vb_uint32 == 12345);
289 TEST_MSG("Expected 12345, got %u", dst.vb_uint32);
290
291 fr_value_box_clear(&src);
292}
293
295{
296 fr_value_box_t src, dst;
297
298 fr_value_box(&src, (int32_t) -42, false);
300
301 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_INT64, NULL, &src) == 0);
302 TEST_CHECK(dst.type == FR_TYPE_INT64);
303 TEST_CHECK(dst.vb_int64 == -42);
304}
305
307{
308 fr_value_box_t src, dst;
309
310 fr_value_box(&src, (uint8_t) 255, false);
312
313 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT32, NULL, &src) == 0);
314 TEST_CHECK(dst.type == FR_TYPE_UINT32);
315 TEST_CHECK(dst.vb_uint32 == 255);
316}
317
318static void test_cast_same_type(void)
319{
320 fr_value_box_t src, dst;
321
322 fr_value_box(&src, (uint32_t) 42, false);
324
325 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT32, NULL, &src) == 0);
326 TEST_CHECK(dst.type == FR_TYPE_UINT32);
327 TEST_CHECK(dst.vb_uint32 == 42);
328}
329
331{
332 fr_value_box_t src, dst;
333
334 fr_value_box(&src, (bool) true, false);
336
337 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT32, NULL, &src) == 0);
338 TEST_CHECK(dst.vb_uint32 == 1);
339
340 fr_value_box(&src, (bool) false, false);
341 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT32, NULL, &src) == 0);
342 TEST_CHECK(dst.vb_uint32 == 0);
343}
344
346{
347 fr_value_box_t src, dst;
348
349 fr_value_box(&src, (uint32_t) 1, false);
351
352 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_BOOL, NULL, &src) == 0);
353 TEST_CHECK(dst.vb_bool == true);
354
355 fr_value_box(&src, (uint32_t) 0, false);
356 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_BOOL, NULL, &src) == 0);
357 TEST_CHECK(dst.vb_bool == false);
358}
359
360/*
361 * Cast in place tests
362 */
364{
366
367 fr_value_box(&vb, (uint32_t) 42, false);
368
370 TEST_CHECK(vb.type == FR_TYPE_UINT64);
371 TEST_CHECK(vb.vb_uint64 == 42);
372}
373
375{
377
378 fr_value_box(&vb, (uint32_t) 12345, false);
379
381 TEST_CHECK(vb.type == FR_TYPE_STRING);
382 TEST_CHECK_STRCMP(vb.vb_strvalue, "12345");
383
385}
386
387/*
388 * Copy tests
389 */
390static void test_copy_uint32(void)
391{
392 fr_value_box_t src, dst;
393
394 fr_value_box(&src, (uint32_t) 42, false);
396
397 TEST_CHECK(fr_value_box_copy(autofree, &dst, &src) == 0);
398 TEST_CHECK(dst.type == FR_TYPE_UINT32);
399 TEST_CHECK(dst.vb_uint32 == 42);
400}
401
402static void test_copy_string(void)
403{
404 fr_value_box_t src, dst;
405
406 fr_value_box_strdup(autofree, &src, NULL, "hello", false);
408
409 TEST_CHECK(fr_value_box_copy(autofree, &dst, &src) == 0);
410 TEST_CHECK(dst.type == FR_TYPE_STRING);
411 TEST_CHECK_STRCMP(dst.vb_strvalue, "hello");
412
413 /* Deep copy: different pointer */
414 TEST_CHECK(dst.vb_strvalue != src.vb_strvalue);
415
416 fr_value_box_clear(&src);
417 fr_value_box_clear(&dst);
418}
419
420static void test_copy_octets(void)
421{
422 fr_value_box_t src, dst;
423
424 fr_value_box_memdup(autofree, &src, NULL, (uint8_t const *)"\x01\x02\x03", 3, false);
426
427 TEST_CHECK(fr_value_box_copy(autofree, &dst, &src) == 0);
428 TEST_CHECK(dst.type == FR_TYPE_OCTETS);
429 TEST_CHECK(dst.vb_length == 3);
430 TEST_CHECK(memcmp(dst.vb_octets, "\x01\x02\x03", 3) == 0);
431
432 /* Deep copy */
433 TEST_CHECK(dst.vb_octets != src.vb_octets);
434
435 fr_value_box_clear(&src);
436 fr_value_box_clear(&dst);
437}
438
440{
441 fr_value_box_t src, dst;
442
443 fr_value_box(&src, (uint32_t) 42, true);
445
446 TEST_CHECK(fr_value_box_copy(autofree, &dst, &src) == 0);
447 TEST_CHECK(dst.tainted == true);
448}
449
450/*
451 * Safety (safe_for) propagation tests
452 *
453 * Tokens standing in for two different consumers. Any two distinct values other
454 * than FR_VALUE_BOX_SAFE_FOR_NONE and FR_VALUE_BOX_SAFE_FOR_ANY will do.
455 */
456#define SAFE_FOR_X ((fr_value_box_safe_for_t) 0x1000)
457#define SAFE_FOR_Y ((fr_value_box_safe_for_t) 0x2000)
458
460{
461 fr_value_box_t src, dst;
462
463 fr_value_box_strdup(autofree, &src, NULL, "copy me", false);
466
467 TEST_CHECK(fr_value_box_copy(autofree, &dst, &src) == 0);
469
470 fr_value_box_clear(&src);
471 fr_value_box_clear(&dst);
472}
473
475{
476 fr_value_box_t src, dst;
477
478 fr_value_box_memdup(autofree, &src, NULL, (uint8_t const *) "abc", 3, false);
481
482 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_STRING, NULL, &src) == 0);
483 TEST_CHECK(dst.type == FR_TYPE_STRING);
485 TEST_MSG("Expected safe_for %#lx, got %#lx", (unsigned long) SAFE_FOR_X, (unsigned long) dst.vb_safefor);
486
487 fr_value_box_clear(&src);
488 fr_value_box_clear(&dst);
489}
490
492{
493 fr_value_box_t src, dst;
494
495 fr_value_box_strdup(autofree, &src, NULL, "abc", false);
498
499 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_OCTETS, NULL, &src) == 0);
500 TEST_CHECK(dst.type == FR_TYPE_OCTETS);
502 TEST_MSG("Expected safe_for %#lx, got %#lx", (unsigned long) SAFE_FOR_X, (unsigned long) dst.vb_safefor);
503
504 fr_value_box_clear(&src);
505 fr_value_box_clear(&dst);
506}
507
509{
510 fr_value_box_t src, dst;
511
512 fr_value_box(&src, (uint32_t) 12345, false);
515
516 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_STRING, NULL, &src) == 0);
517 TEST_CHECK(dst.type == FR_TYPE_STRING);
518 TEST_CHECK(dst.vb_safefor == FR_VALUE_BOX_SAFE_FOR_NONE);
519 TEST_MSG("Expected safe_for NONE, got %#lx", (unsigned long) dst.vb_safefor);
520
521 fr_value_box_clear(&dst);
522}
523
524/** Build a list of single character string boxes, each marked with the matching token
525 */
526static void safe_for_list_build(fr_value_box_list_t *list, fr_value_box_safe_for_t const tokens[], size_t num)
527{
528 size_t i;
529
530 fr_value_box_list_init(list);
531 for (i = 0; i < num; i++) {
532 fr_value_box_t *vb;
533
535 TEST_ASSERT(vb != NULL);
536 TEST_ASSERT(fr_value_box_strdup(vb, vb, NULL, "x", false) == 0);
537 fr_value_box_mark_safe_for(vb, tokens[i]);
538 fr_value_box_list_insert_tail(list, vb);
539 }
540}
541
542/** Concatenate a list into a separate output box and check the resulting safe_for
543 */
544static void safe_for_concat_check(fr_type_t type, fr_value_box_safe_for_t const tokens[], size_t num,
546{
547 fr_value_box_list_t list;
549
550 safe_for_list_build(&list, tokens, num);
552
554 FR_VALUE_BOX_LIST_FREE, true, SIZE_MAX) == 0);
555 TEST_CHECK(out.type == type);
556 TEST_CHECK(out.vb_length == num);
557 TEST_CHECK(out.vb_safefor == expect);
558 TEST_MSG("Expected safe_for %#lx, got %#lx", (unsigned long) expect, (unsigned long) out.vb_safefor);
559
561}
562
569
570static void test_concat_x_x_is_x(void)
571{
572 fr_value_box_safe_for_t const tokens[] = { SAFE_FOR_X, SAFE_FOR_X };
573
575}
576
583
590
597
604
606{
607 fr_value_box_safe_for_t const tokens[] = { SAFE_FOR_X, SAFE_FOR_X };
608
610}
611
612/** The list head doubles as the output box
613 */
615{
616 fr_value_box_safe_for_t const tokens[] = { SAFE_FOR_X, SAFE_FOR_X };
617 fr_value_box_list_t list;
619
620 safe_for_list_build(&list, tokens, NUM_ELEMENTS(tokens));
621 head = fr_value_box_list_head(&list);
622
624 FR_VALUE_BOX_LIST_FREE, true, SIZE_MAX) == 0);
625 TEST_CHECK(head->vb_length == 2);
627 TEST_MSG("Expected safe_for %#lx, got %#lx", (unsigned long) SAFE_FOR_X, (unsigned long) head->vb_safefor);
628
629 fr_value_box_list_talloc_free(&list);
630}
631
632static void test_list_safety_merge(void)
633{
636 fr_value_box_safe_for_t const x_only[] = { SAFE_FOR_X };
637 fr_value_box_list_t list;
638 fr_value_box_t out, *group;
639
640 TEST_CASE("X and ANY merge to X");
641 safe_for_list_build(&list, x_any, NUM_ELEMENTS(x_any));
645 fr_value_box_list_talloc_free(&list);
646
647 TEST_CASE("X and Y merge to NONE");
648 safe_for_list_build(&list, x_y, NUM_ELEMENTS(x_y));
652 fr_value_box_list_talloc_free(&list);
653
654 TEST_CASE("Group children are merged, the group box itself is not");
655 fr_value_box_list_init(&list);
657 TEST_ASSERT(group != NULL);
658 safe_for_list_build(&group->vb_group, x_only, NUM_ELEMENTS(x_only));
659 fr_value_box_list_insert_tail(&list, group);
663 fr_value_box_list_talloc_free(&list);
664}
665
666/*
667 * String operations
668 */
669static void test_strdup(void)
670{
672
673 TEST_CHECK(fr_value_box_strdup(autofree, &vb, NULL, "hello world", false) == 0);
674 TEST_CHECK(vb.type == FR_TYPE_STRING);
675 TEST_CHECK_STRCMP(vb.vb_strvalue, "hello world");
676 TEST_CHECK(vb.vb_length == 11);
677
679}
680
681static void test_asprintf(void)
682{
684
685 TEST_CHECK(fr_value_box_asprintf(autofree, &vb, NULL, false, "value=%d", 42) == 0);
686 TEST_CHECK(vb.type == FR_TYPE_STRING);
687 TEST_CHECK_STRCMP(vb.vb_strvalue, "value=42");
688
690}
691
692static void test_bstrndup(void)
693{
695
696 /* bstrndup copies exactly len bytes */
697 TEST_CHECK(fr_value_box_bstrndup(autofree, &vb, NULL, "hello\0world", 11, false) == 0);
698 TEST_CHECK(vb.type == FR_TYPE_STRING);
699 TEST_CHECK(vb.vb_length == 11);
700 TEST_CHECK(memcmp(vb.vb_strvalue, "hello\0world", 11) == 0);
701
703}
704
705/*
706 * Memory operations
707 */
708static void test_memdup(void)
709{
711 uint8_t data[] = { 0xde, 0xad, 0xbe, 0xef };
712
713 TEST_CHECK(fr_value_box_memdup(autofree, &vb, NULL, data, sizeof(data), false) == 0);
714 TEST_CHECK(vb.type == FR_TYPE_OCTETS);
715 TEST_CHECK(vb.vb_length == 4);
716 TEST_CHECK(memcmp(vb.vb_octets, data, 4) == 0);
717
719}
720
721/*
722 * Hash tests
723 */
724static void test_hash_same_values(void)
725{
726 fr_value_box_t a, b;
727
728 fr_value_box(&a, (uint32_t) 42, false);
729 fr_value_box(&b, (uint32_t) 42, false);
730
732}
733
735{
736 fr_value_box_t a, b;
737
738 fr_value_box(&a, (uint32_t) 42, false);
739 fr_value_box(&b, (uint32_t) 43, false);
740
742}
743
744static void test_hash_string(void)
745{
746 fr_value_box_t a, b;
747
748 fr_value_box_strdup(autofree, &a, NULL, "hello", false);
749 fr_value_box_strdup(autofree, &b, NULL, "hello", false);
750
752
755}
756
757/*
758 * Truthiness tests (fr_value_box_is_truthy)
759 */
760static void test_truthy_bool(void)
761{
763
764 fr_value_box(&vb, (bool) true, false);
766
767 fr_value_box(&vb, (bool) false, false);
768 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
769}
770
771static void test_truthy_uint32(void)
772{
774
775 fr_value_box(&vb, (uint32_t) 42, false);
777
778 fr_value_box(&vb, (uint32_t) 0, false);
779 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
780}
781
782static void test_truthy_string(void)
783{
785
786 fr_value_box_strdup(autofree, &vb, NULL, "hello", false);
789
790 fr_value_box_strdup(autofree, &vb, NULL, "", false);
791 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
793}
794
795static void test_truthy_octets(void)
796{
798
799 fr_value_box_memdup(autofree, &vb, NULL, (uint8_t const *)"\x01", 1, false);
802
803 fr_value_box_memdup(autofree, &vb, NULL, (uint8_t const *)"", 0, false);
804 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
806}
807
808/*
809 * Increment tests (fr_value_box_increment)
810 */
811static void test_increment_uint32(void)
812{
814
815 fr_value_box(&vb, (uint32_t) 41, false);
817 TEST_CHECK(vb.vb_uint32 == 42);
818 TEST_MSG("Expected 42, got %u", vb.vb_uint32);
819}
820
822{
824
825 fr_value_box(&vb, (uint8_t) UINT8_MAX, false);
827 TEST_CHECK(vb.vb_uint8 == 0);
828 TEST_MSG("Expected 0 (wrap), got %u", vb.vb_uint8);
829}
830
831static void test_increment_int32(void)
832{
834
835 fr_value_box(&vb, (int32_t) -1, false);
837 TEST_CHECK(vb.vb_int32 == 0);
838 TEST_MSG("Expected 0, got %d", vb.vb_int32);
839}
840
841/*
842 * as_uint64 extraction tests
843 */
844static void test_as_uint64(void)
845{
847
848 fr_value_box(&vb, (uint8_t) 255, false);
850
851 fr_value_box(&vb, (uint16_t) 1000, false);
853
854 fr_value_box(&vb, (uint32_t) 100000, false);
855 TEST_CHECK(fr_value_box_as_uint64(&vb) == 100000);
856
857 fr_value_box(&vb, (uint64_t) UINT64_MAX, false);
858 TEST_CHECK(fr_value_box_as_uint64(&vb) == UINT64_MAX);
859
860 fr_value_box(&vb, (bool) true, false);
862}
863
864/*
865 * Clear tests
866 */
867static void test_clear(void)
868{
870
871 fr_value_box(&vb, (uint32_t) 42, false);
872 TEST_CHECK(vb.type == FR_TYPE_UINT32);
873
875 TEST_CHECK(vb.type == FR_TYPE_NULL);
876}
877
878static void test_clear_string(void)
879{
881
882 fr_value_box_strdup(autofree, &vb, NULL, "hello", false);
883 TEST_CHECK(vb.type == FR_TYPE_STRING);
884
886 TEST_CHECK(vb.type == FR_TYPE_NULL);
887}
888
889/*
890 * Tainted flag tests
891 */
892static void test_tainted_flag(void)
893{
895
896 fr_value_box(&vb, (uint32_t) 42, true);
897 TEST_CHECK(vb.tainted == true);
898
899 fr_value_box(&vb, (uint32_t) 42, false);
900 TEST_CHECK(vb.tainted == false);
901}
902
903/*
904 * Network encode/decode round-trip tests
905 */
906static void test_network_uint32(void)
907{
908 fr_value_box_t src, dst;
909 uint8_t buffer[256] = {};
910 fr_dbuff_t dbuff;
911 ssize_t enc_len, dec_len;
912
913 fr_value_box(&src, (uint32_t) 0x12345678, false);
914
915 /* Encode to network format */
916 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
917 enc_len = fr_value_box_to_network(&dbuff, &src);
918 TEST_CHECK(enc_len == 4);
919
920 /* Verify network byte order (big endian) */
921 TEST_CHECK(buffer[0] == 0x12);
922 TEST_CHECK(buffer[1] == 0x34);
923 TEST_CHECK(buffer[2] == 0x56);
924 TEST_CHECK(buffer[3] == 0x78);
925
926 /* Decode back */
928 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
929 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_UINT32, NULL, &dbuff, enc_len, false);
930 TEST_CHECK(dec_len == 4);
931 TEST_CHECK(dst.vb_uint32 == 0x12345678);
932 TEST_MSG("Expected 0x12345678, got 0x%08x", dst.vb_uint32);
933}
934
935static void test_network_uint64(void)
936{
937 fr_value_box_t src, dst;
938 uint8_t buffer[256] = {};
939 fr_dbuff_t dbuff;
940 ssize_t enc_len, dec_len;
941
942 fr_value_box(&src, (uint64_t) 0x0102030405060708ULL, false);
943
944 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
945 enc_len = fr_value_box_to_network(&dbuff, &src);
946 TEST_CHECK(enc_len == 8);
947
948 /* Verify big endian */
949 TEST_CHECK(buffer[0] == 0x01);
950 TEST_CHECK(buffer[7] == 0x08);
951
952 /* Decode back */
954 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
955 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_UINT64, NULL, &dbuff, enc_len, false);
956 TEST_CHECK(dec_len == 8);
957 TEST_CHECK(dst.vb_uint64 == 0x0102030405060708ULL);
958}
959
960static void test_network_int32(void)
961{
962 fr_value_box_t src, dst;
963 uint8_t buffer[256] = {};
964 fr_dbuff_t dbuff;
965 ssize_t enc_len, dec_len;
966
967 fr_value_box(&src, (int32_t) -1, false);
968
969 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
970 enc_len = fr_value_box_to_network(&dbuff, &src);
971 TEST_CHECK(enc_len == 4);
972
973 /* -1 in two's complement big endian is 0xffffffff */
974 TEST_CHECK(buffer[0] == 0xff);
975 TEST_CHECK(buffer[1] == 0xff);
976 TEST_CHECK(buffer[2] == 0xff);
977 TEST_CHECK(buffer[3] == 0xff);
978
979 /* Decode back */
981 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
982 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_INT32, NULL, &dbuff, enc_len, false);
983 TEST_CHECK(dec_len == 4);
984 TEST_CHECK(dst.vb_int32 == -1);
985}
986
987static void test_network_bool(void)
988{
989 fr_value_box_t src, dst;
990 uint8_t buffer[256] = {};
991 fr_dbuff_t dbuff;
992 ssize_t enc_len, dec_len;
993
994 fr_value_box(&src, (bool) true, false);
995
996 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
997 enc_len = fr_value_box_to_network(&dbuff, &src);
998 TEST_CHECK(enc_len == 1);
999 TEST_CHECK(buffer[0] == 1);
1000
1002 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
1003 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_BOOL, NULL, &dbuff, enc_len, false);
1004 TEST_CHECK(dec_len == 1);
1005 TEST_CHECK(dst.vb_bool == true);
1006}
1007
1008static void test_network_length(void)
1009{
1010 fr_value_box_t vb;
1011
1012 fr_value_box(&vb, (uint8_t) 0, false);
1014
1015 fr_value_box(&vb, (uint16_t) 0, false);
1017
1018 fr_value_box(&vb, (uint32_t) 0, false);
1020
1021 fr_value_box(&vb, (uint64_t) 0, false);
1023}
1024
1025/*
1026 * Print tests (fr_value_box_print)
1027 */
1028static void test_print_uint32(void)
1029{
1030 fr_value_box_t vb;
1031 char buffer[256] = {};
1032 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1033
1034 fr_value_box(&vb, (uint32_t) 42, false);
1035
1036 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
1037 fr_sbuff_terminate(&sbuff);
1039}
1040
1042{
1043 fr_value_box_t vb;
1044 char buffer[256] = {};
1045 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1046
1047 fr_value_box(&vb, (int32_t) -42, false);
1048
1049 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
1050 fr_sbuff_terminate(&sbuff);
1051 TEST_CHECK_STRCMP(buffer, "-42");
1052}
1053
1054static void test_print_string(void)
1055{
1056 fr_value_box_t vb;
1057 char buffer[256] = {};
1058 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1059
1060 fr_value_box_strdup(autofree, &vb, NULL, "hello", false);
1061
1062 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
1063 fr_sbuff_terminate(&sbuff);
1064 TEST_CHECK_STRCMP(buffer, "hello");
1065
1066 fr_value_box_clear(&vb);
1067}
1068
1069static void test_print_bool(void)
1070{
1071 fr_value_box_t vb;
1072 char buffer[256] = {};
1073 fr_sbuff_t sbuff;
1074
1075 fr_value_box(&vb, (bool) true, false);
1076 sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1077 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
1078 fr_sbuff_terminate(&sbuff);
1079 TEST_CHECK_STRCMP(buffer, "yes");
1080
1081 fr_value_box(&vb, (bool) false, false);
1082 sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1083 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
1084 fr_sbuff_terminate(&sbuff);
1086}
1087
1088static void test_print_octets(void)
1089{
1090 fr_value_box_t vb;
1091 char buffer[256] = {};
1092 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1093
1094 fr_value_box_memdup(autofree, &vb, NULL, (uint8_t const *)"\xde\xad\xbe\xef", 4, false);
1095
1096 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
1097 fr_sbuff_terminate(&sbuff);
1098 TEST_CHECK_STRCMP(buffer, "0xdeadbeef");
1099
1100 fr_value_box_clear(&vb);
1101}
1102
1103/*
1104 * From string parsing tests (fr_value_box_from_str)
1105 */
1106static void test_from_str_uint32(void)
1107{
1108 fr_value_box_t vb;
1109
1111 "12345", strlen("12345"), NULL) > 0);
1112 TEST_CHECK(vb.type == FR_TYPE_UINT32);
1113 TEST_CHECK(vb.vb_uint32 == 12345);
1114 TEST_MSG("Expected 12345, got %u", vb.vb_uint32);
1115}
1116
1117static void test_from_str_int32(void)
1118{
1119 fr_value_box_t vb;
1120
1122 "-42", strlen("-42"), NULL) > 0);
1123 TEST_CHECK(vb.type == FR_TYPE_INT32);
1124 TEST_CHECK(vb.vb_int32 == -42);
1125 TEST_MSG("Expected -42, got %d", vb.vb_int32);
1126}
1127
1128static void test_from_str_bool(void)
1129{
1130 fr_value_box_t vb;
1131
1133 "yes", strlen("yes"), NULL) > 0);
1134 TEST_CHECK(vb.type == FR_TYPE_BOOL);
1135 TEST_CHECK(vb.vb_bool == true);
1136}
1137
1138static void test_from_str_float64(void)
1139{
1140 fr_value_box_t vb;
1141
1143 "3.14", strlen("3.14"), NULL) > 0);
1144 TEST_CHECK(vb.type == FR_TYPE_FLOAT64);
1145 TEST_CHECK((vb.vb_float64 > 3.13) && (vb.vb_float64 < 3.15));
1146 TEST_MSG("Expected ~3.14, got %f", vb.vb_float64);
1147}
1148
1149static void test_from_str_octets(void)
1150{
1151 fr_value_box_t vb;
1152
1154 "0xdeadbeef", strlen("0xdeadbeef"), NULL) > 0);
1155 TEST_CHECK(vb.type == FR_TYPE_OCTETS);
1156 TEST_CHECK(vb.vb_length == 4);
1157 TEST_CHECK(memcmp(vb.vb_octets, "\xde\xad\xbe\xef", 4) == 0);
1158
1159 fr_value_box_clear(&vb);
1160}
1161
1162static void test_from_str_string(void)
1163{
1164 fr_value_box_t vb;
1165
1167 "hello world", strlen("hello world"), NULL) > 0);
1168 TEST_CHECK(vb.type == FR_TYPE_STRING);
1169 TEST_CHECK_STRCMP(vb.vb_strvalue, "hello world");
1170
1171 fr_value_box_clear(&vb);
1172}
1173
1174/*
1175 * Print/parse round-trip tests
1176 */
1177static void test_round_trip_uint32(void)
1178{
1179 fr_value_box_t src, dst;
1180 char buffer[256] = {};
1181 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1182
1183 fr_value_box(&src, (uint32_t) 42, false);
1184
1185 TEST_CHECK(fr_value_box_print(&sbuff, &src, NULL) > 0);
1186 fr_sbuff_terminate(&sbuff);
1187
1189 buffer, strlen(buffer), NULL) > 0);
1190 TEST_CHECK(dst.vb_uint32 == 42);
1191}
1192
1193static void test_round_trip_int64(void)
1194{
1195 fr_value_box_t src, dst;
1196 char buffer[256] = {};
1197 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1198
1199 fr_value_box(&src, (int64_t) -9999999, false);
1200
1201 TEST_CHECK(fr_value_box_print(&sbuff, &src, NULL) > 0);
1202 fr_sbuff_terminate(&sbuff);
1203
1205 buffer, strlen(buffer), NULL) > 0);
1206 TEST_CHECK(dst.vb_int64 == -9999999);
1207}
1208
1209static void test_round_trip_bool(void)
1210{
1211 fr_value_box_t src, dst;
1212 char buffer[256] = {};
1213 fr_sbuff_t sbuff;
1214
1215 fr_value_box(&src, (bool) true, false);
1216 sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1217 TEST_CHECK(fr_value_box_print(&sbuff, &src, NULL) > 0);
1218 fr_sbuff_terminate(&sbuff);
1219
1221 buffer, strlen(buffer), NULL) > 0);
1222 TEST_CHECK(dst.vb_bool == true);
1223}
1224
1226{
1227 fr_value_box_t src, dst;
1228 uint8_t buffer[256] = {};
1229 fr_dbuff_t dbuff;
1230 ssize_t enc_len;
1231
1232 fr_value_box(&src, (uint32_t) 0xdeadbeef, false);
1233
1234 /* Encode */
1235 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
1236 enc_len = fr_value_box_to_network(&dbuff, &src);
1237 TEST_CHECK(enc_len == 4);
1238
1239 /* Decode */
1241 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
1242 TEST_CHECK(fr_value_box_from_network(NULL, &dst, FR_TYPE_UINT32, NULL, &dbuff, enc_len, false) == 4);
1243 TEST_CHECK(dst.vb_uint32 == 0xdeadbeef);
1244}
1245
1246/** Escape function for the in-place escape tests, writes '%' as "%25"
1247 */
1249{
1250 fr_sbuff_t our_out = FR_SBUFF(out);
1251 fr_sbuff_t our_in = FR_SBUFF(in);
1252
1253 while (fr_sbuff_extend(&our_in)) {
1254 char c = *fr_sbuff_current(&our_in);
1255
1256 if (c == '%') {
1257 FR_SBUFF_IN_STRCPY_LITERAL_RETURN(&our_out, "%25");
1258 } else {
1259 FR_SBUFF_IN_CHAR_RETURN(&our_out, c);
1260 }
1261 fr_sbuff_advance(&our_in, 1);
1262 }
1263
1264 fr_sbuff_set(in, &our_in);
1265 FR_SBUFF_SET_RETURN(out, &our_out);
1266}
1267
1268static void test_bstrndup_replace(void)
1269{
1270 fr_value_box_t *vb;
1271 char const *old;
1272
1273 TEST_CASE("Replacing a string value copies the new bytes and keeps the flags");
1274 vb = fr_value_box_alloc(NULL, FR_TYPE_STRING, NULL);
1275 TEST_ASSERT(vb != NULL);
1276 TEST_ASSERT(fr_value_box_bstrndup(vb, vb, NULL, "before", 6, true) == 0);
1278 old = vb->vb_strvalue;
1279
1280 TEST_CHECK_RET(fr_value_box_bstrndup_replace(vb, vb, "af\0ter", 6), 0);
1281 TEST_CHECK(vb->vb_strvalue != old);
1282 TEST_CHECK_LEN(vb->vb_length, 6);
1283 TEST_CHECK(memcmp(vb->vb_strvalue, "af\0ter", 6) == 0);
1284 TEST_CHECK(vb->vb_strvalue[6] == '\0');
1285 TEST_CHECK(vb->tainted == true);
1287
1288 TEST_CASE("Replacing from an aliased source copies before freeing");
1289 TEST_CHECK_RET(fr_value_box_bstrndup_replace(vb, vb, vb->vb_strvalue + 2, 4), 0);
1290 TEST_CHECK_LEN(vb->vb_length, 4);
1291 TEST_CHECK(memcmp(vb->vb_strvalue, "\0ter", 4) == 0);
1292
1293 talloc_free(vb);
1294}
1295
1297{
1298 fr_value_box_t *vb;
1299
1300 TEST_CASE("String with escapable characters and an embedded NUL");
1301 vb = fr_value_box_alloc(NULL, FR_TYPE_STRING, NULL);
1302 TEST_ASSERT(vb != NULL);
1303 TEST_ASSERT(fr_value_box_bstrndup(vb, vb, NULL, "a%b\0c", 5, true) == 0);
1304
1306 TEST_CHECK_LEN(vb->vb_length, 7);
1307 TEST_CHECK(memcmp(vb->vb_strvalue, "a%25b\0c", 7) == 0);
1308 TEST_CHECK(vb->vb_strvalue[7] == '\0');
1309 TEST_CHECK(vb->tainted == true);
1310
1311 talloc_free(vb);
1312}
1313
1315{
1316 fr_value_box_t *vb;
1317
1318 TEST_CASE("String with nothing to escape is copied as is");
1319 vb = fr_value_box_alloc(NULL, FR_TYPE_STRING, NULL);
1320 TEST_ASSERT(vb != NULL);
1321 TEST_ASSERT(fr_value_box_strdup(vb, vb, NULL, "plain", false) == 0);
1322
1324 TEST_CHECK_STRCMP(vb->vb_strvalue, "plain");
1325 TEST_CHECK_LEN(vb->vb_length, 5);
1326
1327 talloc_free(vb);
1328}
1329
1331{
1332 fr_value_box_t *vb;
1333
1334 TEST_CASE("Non-string input is cast to a string before escaping");
1335 vb = fr_value_box_alloc(NULL, FR_TYPE_UINT32, NULL);
1336 TEST_ASSERT(vb != NULL);
1337 vb->vb_uint32 = 100;
1338
1340 TEST_CHECK(vb->type == FR_TYPE_STRING);
1341 TEST_CHECK_STRCMP(vb->vb_strvalue, "100");
1342
1343 talloc_free(vb);
1344}
1345
1347 /* Value replacement and in place escaping */
1348 { "bstrndup_replace", test_bstrndup_replace },
1349 { "escape_in_place_func_string", test_escape_in_place_func_string },
1350 { "escape_in_place_func_unchanged", test_escape_in_place_func_unchanged },
1351 { "escape_in_place_func_cast", test_escape_in_place_func_cast },
1352
1353 /* Comparison tests */
1354 { "cmp_uint32_equal", test_cmp_uint32_equal },
1355 { "cmp_uint32_less", test_cmp_uint32_less },
1356 { "cmp_int32", test_cmp_int32 },
1357 { "cmp_float64", test_cmp_float64 },
1358 { "cmp_string", test_cmp_string },
1359 { "cmp_octets", test_cmp_octets },
1360 { "cmp_octets_length", test_cmp_octets_length },
1361 { "cmp_bool", test_cmp_bool },
1362 { "cmp_different_types", test_cmp_different_types },
1363
1364 /* Comparison operator tests */
1365 { "cmp_op_eq", test_cmp_op_eq },
1366 { "cmp_op_ne", test_cmp_op_ne },
1367 { "cmp_op_lt", test_cmp_op_lt },
1368 { "cmp_op_gt", test_cmp_op_gt },
1369 { "cmp_op_le", test_cmp_op_le },
1370 { "cmp_op_ge", test_cmp_op_ge },
1371
1372 /* Cast tests */
1373 { "cast_uint32_to_uint64", test_cast_uint32_to_uint64 },
1374 { "cast_uint32_to_string", test_cast_uint32_to_string },
1375 { "cast_string_to_uint32", test_cast_string_to_uint32 },
1376 { "cast_int32_to_int64", test_cast_int32_to_int64 },
1377 { "cast_uint8_to_uint32", test_cast_uint8_to_uint32 },
1378 { "cast_same_type", test_cast_same_type },
1379 { "cast_bool_to_uint32", test_cast_bool_to_uint32 },
1380 { "cast_uint32_to_bool", test_cast_uint32_to_bool },
1381
1382 /* Cast in place */
1383 { "cast_in_place_uint32_to_uint64", test_cast_in_place_uint32_to_uint64 },
1384 { "cast_in_place_uint32_to_string", test_cast_in_place_uint32_to_string },
1385
1386 /* Copy tests */
1387 { "copy_uint32", test_copy_uint32 },
1388 { "copy_string", test_copy_string },
1389 { "copy_octets", test_copy_octets },
1390 { "copy_preserves_tainted", test_copy_preserves_tainted },
1391
1392 /* Safety propagation */
1393 { "copy_preserves_safe_for", test_copy_preserves_safe_for },
1394 { "cast_octets_to_string_preserves_safe_for", test_cast_octets_to_string_preserves_safe_for },
1395 { "cast_string_to_octets_preserves_safe_for", test_cast_string_to_octets_preserves_safe_for },
1396 { "cast_uint32_to_string_clears_safe_for", test_cast_uint32_to_string_clears_safe_for },
1397 { "concat_any_any_is_any", test_concat_any_any_is_any },
1398 { "concat_x_x_is_x", test_concat_x_x_is_x },
1399 { "concat_x_any_is_x", test_concat_x_any_is_x },
1400 { "concat_any_x_is_x", test_concat_any_x_is_x },
1401 { "concat_x_y_is_none", test_concat_x_y_is_none },
1402 { "concat_x_none_is_none", test_concat_x_none_is_none },
1403 { "concat_octets_x_x_is_x", test_concat_octets_x_x_is_x },
1404 { "concat_into_head_x_x_is_x", test_concat_into_head_x_x_is_x },
1405 { "list_safety_merge", test_list_safety_merge },
1406
1407 /* String operations */
1408 { "strdup", test_strdup },
1409 { "asprintf", test_asprintf },
1410 { "bstrndup", test_bstrndup },
1411
1412 /* Memory operations */
1413 { "memdup", test_memdup },
1414
1415 /* Hash tests */
1416 { "hash_same_values", test_hash_same_values },
1417 { "hash_different_values", test_hash_different_values },
1418 { "hash_string", test_hash_string },
1419
1420 /* Truthiness tests */
1421 { "truthy_bool", test_truthy_bool },
1422 { "truthy_uint32", test_truthy_uint32 },
1423 { "truthy_string", test_truthy_string },
1424 { "truthy_octets", test_truthy_octets },
1425
1426 /* Increment tests */
1427 { "increment_uint32", test_increment_uint32 },
1428 { "increment_uint8_overflow", test_increment_uint8_overflow },
1429 { "increment_int32", test_increment_int32 },
1430
1431 /* as_uint64 */
1432 { "as_uint64", test_as_uint64 },
1433
1434 /* Clear tests */
1435 { "clear", test_clear },
1436 { "clear_string", test_clear_string },
1437
1438 /* Tainted flag */
1439 { "tainted_flag", test_tainted_flag },
1440
1441 /* Network encode/decode */
1442 { "network_uint32", test_network_uint32 },
1443 { "network_uint64", test_network_uint64 },
1444 { "network_int32", test_network_int32 },
1445 { "network_bool", test_network_bool },
1446 { "network_length", test_network_length },
1447
1448 /* Print tests */
1449 { "print_uint32", test_print_uint32 },
1450 { "print_int32_negative", test_print_int32_negative },
1451 { "print_string", test_print_string },
1452 { "print_bool", test_print_bool },
1453 { "print_octets", test_print_octets },
1454
1455 /* From string parsing */
1456 { "from_str_uint32", test_from_str_uint32 },
1457 { "from_str_int32", test_from_str_int32 },
1458 { "from_str_bool", test_from_str_bool },
1459 { "from_str_float64", test_from_str_float64 },
1460 { "from_str_octets", test_from_str_octets },
1461 { "from_str_string", test_from_str_string },
1462
1463 /* Round-trip tests */
1464 { "round_trip_uint32", test_round_trip_uint32 },
1465 { "round_trip_int64", test_round_trip_int64 },
1466 { "round_trip_bool", test_round_trip_bool },
1467 { "round_trip_network_uint32", test_round_trip_network_uint32 },
1468
1470};
static int const char char buffer[256]
Definition acutest.h:576
#define TEST_CHECK(cond)
Definition acutest.h:87
#define TEST_CASE(name)
Definition acutest.h:186
#define TEST_ASSERT(cond)
Definition acutest.h:110
#define TEST_TERMINATOR
Definition acutest.h:64
#define TEST_MSG(...)
Definition acutest.h:217
Common initialisation for acutest binaries.
#define TEST_CHECK_LEN(_got, _exp)
#define TEST_CHECK_RET(_got, _exp)
#define TEST_CHECK_STRCMP(_got, _exp)
#define NUM_ELEMENTS(_t)
Definition build.h:406
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition dbuff.h:522
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition debug.h:272
static fr_slen_t in
Definition dict.h:906
#define __attribute__(x)
Definition filenames.h:38
talloc_free(hp)
unsigned short uint16_t
fr_type_t
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_INT32
32 Bit signed integer.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_GROUP
A grouping of other attributes.
@ FR_TYPE_FLOAT64
Double precision floating point.
unsigned int uint32_t
long int ssize_t
unsigned char uint8_t
ssize_t fr_slen_t
#define UINT8_MAX
@ CMP_ERR
comparison failed
Definition misc.h:51
#define FR_SBUFF_IN_CHAR_RETURN(_sbuff,...)
#define fr_sbuff_set(_dst, _src)
#define fr_sbuff_current(_sbuff_or_marker)
#define FR_SBUFF_IN_STRCPY_LITERAL_RETURN(_sbuff, _str)
#define fr_sbuff_extend(_sbuff_or_marker)
#define FR_SBUFF_SET_RETURN(_dst, _src)
#define FR_SBUFF(_sbuff_or_marker)
#define fr_sbuff_advance(_sbuff_or_marker, _len)
#define FR_SBUFF_OUT(_start, _len_or_end)
fr_aka_sim_id_type_t type
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition talloc.h:55
@ T_OP_NE
Definition token.h:95
@ T_OP_CMP_EQ
Definition token.h:104
@ T_OP_LE
Definition token.h:98
@ T_OP_GE
Definition token.h:96
@ T_OP_GT
Definition token.h:97
@ T_OP_LT
Definition token.h:99
static fr_slen_t head
Definition xlat.h:410
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_cmp_ret_t fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b)
Compare two values.
Definition value.c:761
fr_slen_t fr_value_box_from_str(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, char const *in, size_t inlen, fr_sbuff_unescape_rules_t const *erules)
Definition value.c:6132
size_t fr_value_box_network_length(fr_value_box_t const *value)
Get the size of the value held by the fr_value_box_t.
Definition value.c:1425
uint32_t fr_value_box_hash(fr_value_box_t const *vb)
Hash the contents of a value box.
Definition value.c:7196
ssize_t fr_value_box_print(fr_sbuff_t *out, fr_value_box_t const *data, fr_sbuff_escape_rules_t const *e_rules)
Print one boxed value to a string.
Definition value.c:6169
ssize_t fr_value_box_from_network(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t type, fr_dict_attr_t const *enumv, fr_dbuff_t *dbuff, size_t len, bool tainted)
Decode a fr_value_box_t from serialized binary data.
Definition value.c:1908
int fr_value_box_cast(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv, fr_value_box_t const *src)
Convert one type of fr_value_box_t to another.
Definition value.c:3974
int fr_value_box_asprintf(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, bool tainted, char const *fmt,...)
Print a formatted string using our internal printf wrapper and assign it to a value box.
Definition value.c:4737
int fr_value_box_escape_in_place_func(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_sbuff_escape_func_t escape)
Escape a value box in place using an sbuff escape function.
Definition value.c:7044
int fr_value_box_copy(TALLOC_CTX *ctx, fr_value_box_t *dst, const fr_value_box_t *src)
Copy value data verbatim duplicating any buffers.
Definition value.c:4422
int fr_value_box_cmp_op(fr_token_t op, fr_value_box_t const *a, fr_value_box_t const *b)
Compare two attributes using an operator.
Definition value.c:1008
int fr_value_box_bstrndup_replace(TALLOC_CTX *ctx, fr_value_box_t *vb, char const *src, ssize_t len)
Free the existing buffer (if talloced) associated with the valuebox, and replace it with a copy of a ...
Definition value.c:4795
uint64_t fr_value_box_as_uint64(fr_value_box_t const *vb)
Return a uint64_t from a fr_value_box_t.
Definition value.c:4274
bool fr_value_box_is_truthy(fr_value_box_t const *in)
Check truthiness of values.
Definition value.c:7560
int fr_value_box_cast_in_place(TALLOC_CTX *ctx, fr_value_box_t *vb, fr_type_t dst_type, fr_dict_attr_t const *dst_enumv)
Convert one type of fr_value_box_t to another in place.
Definition value.c:4224
void fr_value_box_increment(fr_value_box_t *vb)
Increment a boxed value.
Definition value.c:5317
int fr_value_box_strdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, bool tainted)
Copy a nul terminated string to a fr_value_box_t.
Definition value.c:4649
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
Definition value.c:4405
ssize_t fr_value_box_to_network(fr_dbuff_t *dbuff, fr_value_box_t const *value)
Encode a single value box, serializing its contents in generic network format.
Definition value.c:1511
void fr_value_box_list_safety_merge(fr_value_box_t *out, fr_value_box_list_t const *list)
Set the safety of out to the most restrictive safety of any leaf box in a list.
Definition value.c:7543
int fr_value_box_bstrndup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, char const *src, size_t len, bool tainted)
Copy a string to to a fr_value_box_t.
Definition value.c:4900
int fr_value_box_memdup(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_dict_attr_t const *enumv, uint8_t const *src, size_t len, bool tainted)
Copy a buffer to a fr_value_box_t.
Definition value.c:5141
int fr_value_box_list_concat_in_place(TALLOC_CTX *ctx, fr_value_box_t *out, fr_value_box_list_t *list, fr_type_t type, fr_value_box_list_action_t proc_action, bool flatten, size_t max_size)
Concatenate a list of value boxes.
Definition value.c:6669
@ FR_VALUE_BOX_LIST_FREE
Definition value.h:261
#define fr_value_box_alloc(_ctx, _type, _enumv)
Allocate a value box of a specific type.
Definition value.h:669
#define fr_value_box_mark_safe_for(_box, _safe_for)
Definition value.h:1125
static fr_slen_t data
Definition value.h:1367
#define fr_value_box_is_safe_for_only(_box, _safe_for)
Definition value.h:1133
#define fr_value_box_init_null(_vb)
Initialise an empty/null box that will be filled later.
Definition value.h:641
#define fr_value_box(_box, _var, _tainted)
Automagically fill in a box, determining the value type from the type of the C variable.
Definition value.h:936
#define FR_VALUE_BOX_SAFE_FOR_NONE
Definition value.h:172
uintptr_t fr_value_box_safe_for_t
Escaping that's been applied to a value box.
Definition value.h:162
static size_t char ** out
Definition value.h:1062
#define FR_VALUE_BOX_SAFE_FOR_ANY
Definition value.h:173
static void test_clear(void)
static void test_escape_in_place_func_cast(void)
static void test_cmp_int32(void)
Definition value_tests.c:69
static void test_strdup(void)
static void test_copy_string(void)
static void test_tainted_flag(void)
static void test_from_str_int32(void)
static void test_cast_uint32_to_string_clears_safe_for(void)
TEST_LIST
static void test_cmp_op_ge(void)
static void test_cmp_uint32_equal(void)
Definition value_tests.c:48
static void test_cmp_op_ne(void)
static void test_concat_x_y_is_none(void)
static void test_cmp_octets_length(void)
static void safe_for_list_build(fr_value_box_list_t *list, fr_value_box_safe_for_t const tokens[], size_t num)
Build a list of single character string boxes, each marked with the matching token.
static void test_concat_x_none_is_none(void)
static void test_round_trip_network_uint32(void)
static void test_network_int32(void)
static void test_cast_uint32_to_uint64(void)
static void test_as_uint64(void)
static void test_from_str_float64(void)
static void test_from_str_string(void)
static void test_print_octets(void)
static void test_network_uint32(void)
static TALLOC_CTX * autofree
Definition value_tests.c:28
static void test_round_trip_uint32(void)
static void test_copy_uint32(void)
static void test_print_string(void)
static void test_round_trip_int64(void)
static void test_asprintf(void)
static void test_print_uint32(void)
static void test_network_uint64(void)
static void test_network_length(void)
static void test_concat_into_head_x_x_is_x(void)
The list head doubles as the output box.
static void test_cast_uint32_to_string(void)
static void test_cast_octets_to_string_preserves_safe_for(void)
static void test_bstrndup(void)
static void test_print_int32_negative(void)
static void test_increment_uint32(void)
static void test_concat_any_x_is_x(void)
static void test_bstrndup_replace(void)
static void test_cast_int32_to_int64(void)
static void test_round_trip_bool(void)
static void test_cast_in_place_uint32_to_string(void)
static void test_list_safety_merge(void)
static void test_increment_uint8_overflow(void)
static void test_truthy_bool(void)
static void test_hash_different_values(void)
static void test_cast_uint8_to_uint32(void)
static void test_escape_in_place_func_string(void)
static void test_cmp_op_lt(void)
static void test_cast_same_type(void)
static void test_cmp_octets(void)
static void test_copy_preserves_safe_for(void)
static void test_cast_bool_to_uint32(void)
static void test_escape_in_place_func_unchanged(void)
static void test_from_str_bool(void)
static void test_concat_x_any_is_x(void)
static void test_concat_octets_x_x_is_x(void)
static void test_cmp_op_eq(void)
static void test_cast_in_place_uint32_to_uint64(void)
static void test_cast_uint32_to_bool(void)
static void test_copy_preserves_tainted(void)
static void test_cmp_different_types(void)
static void test_concat_any_any_is_any(void)
static void test_concat_x_x_is_x(void)
static void test_cmp_string(void)
Definition value_tests.c:97
static void test_hash_same_values(void)
static fr_slen_t test_percent_escape(fr_sbuff_t *out, fr_sbuff_t *in)
Escape function for the in-place escape tests, writes '' as "%25".
static void test_cmp_float64(void)
Definition value_tests.c:83
static void test_truthy_octets(void)
static void test_from_str_octets(void)
static void test_cast_string_to_uint32(void)
static void test_clear_string(void)
static void test_init(void)
Definition value_tests.c:30
static void test_hash_string(void)
static void test_cmp_op_le(void)
static void test_truthy_uint32(void)
static void test_memdup(void)
static void test_increment_int32(void)
static void test_cmp_op_gt(void)
static void safe_for_concat_check(fr_type_t type, fr_value_box_safe_for_t const tokens[], size_t num, fr_value_box_safe_for_t expect)
Concatenate a list into a separate output box and check the resulting safe_for.
static void test_print_bool(void)
static void test_truthy_string(void)
static void test_cmp_bool(void)
#define SAFE_FOR_Y
static void test_cmp_uint32_less(void)
Definition value_tests.c:58
static void test_cast_string_to_octets_preserves_safe_for(void)
static void test_copy_octets(void)
static void test_from_str_uint32(void)
static void test_network_bool(void)
#define SAFE_FOR_X