The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
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.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 should return < -1 (error) */
166 TEST_CHECK(fr_value_box_cmp(&a, &b) < -1);
167}
168
169/*
170 * Comparison operator tests (fr_value_box_cmp_op)
171 */
172static void test_cmp_op_eq(void)
173{
174 fr_value_box_t a, b;
175
176 fr_value_box(&a, (uint32_t) 42, false);
177 fr_value_box(&b, (uint32_t) 42, false);
178
180
181 fr_value_box(&b, (uint32_t) 43, false);
183}
184
185static void test_cmp_op_ne(void)
186{
187 fr_value_box_t a, b;
188
189 fr_value_box(&a, (uint32_t) 42, false);
190 fr_value_box(&b, (uint32_t) 43, false);
191
193
194 fr_value_box(&b, (uint32_t) 42, false);
196}
197
198static void test_cmp_op_lt(void)
199{
200 fr_value_box_t a, b;
201
202 fr_value_box(&a, (uint32_t) 10, false);
203 fr_value_box(&b, (uint32_t) 20, false);
204
208}
209
210static void test_cmp_op_gt(void)
211{
212 fr_value_box_t a, b;
213
214 fr_value_box(&a, (uint32_t) 20, false);
215 fr_value_box(&b, (uint32_t) 10, false);
216
219}
220
221static void test_cmp_op_le(void)
222{
223 fr_value_box_t a, b;
224
225 fr_value_box(&a, (uint32_t) 10, false);
226 fr_value_box(&b, (uint32_t) 20, false);
227
230
231 fr_value_box(&b, (uint32_t) 10, false);
233}
234
235static void test_cmp_op_ge(void)
236{
237 fr_value_box_t a, b;
238
239 fr_value_box(&a, (uint32_t) 20, false);
240 fr_value_box(&b, (uint32_t) 10, false);
241
244
245 fr_value_box(&b, (uint32_t) 20, false);
247}
248
249/*
250 * Cast tests (fr_value_box_cast)
251 */
253{
254 fr_value_box_t src, dst;
255
256 fr_value_box(&src, (uint32_t) 42, false);
258
259 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT64, NULL, &src) == 0);
260 TEST_CHECK(dst.type == FR_TYPE_UINT64);
261 TEST_CHECK(dst.vb_uint64 == 42);
262}
263
265{
266 fr_value_box_t src, dst;
267
268 fr_value_box(&src, (uint32_t) 12345, false);
270
271 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_STRING, NULL, &src) == 0);
272 TEST_CHECK(dst.type == FR_TYPE_STRING);
273 TEST_CHECK_STRCMP(dst.vb_strvalue, "12345");
274
275 fr_value_box_clear(&dst);
276}
277
279{
280 fr_value_box_t src, dst;
281
282 fr_value_box_strdup(autofree, &src, NULL, "12345", false);
284
285 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT32, NULL, &src) >= 0);
286 TEST_CHECK(dst.type == FR_TYPE_UINT32);
287 TEST_CHECK(dst.vb_uint32 == 12345);
288 TEST_MSG("Expected 12345, got %u", dst.vb_uint32);
289
290 fr_value_box_clear(&src);
291}
292
294{
295 fr_value_box_t src, dst;
296
297 fr_value_box(&src, (int32_t) -42, false);
299
300 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_INT64, NULL, &src) == 0);
301 TEST_CHECK(dst.type == FR_TYPE_INT64);
302 TEST_CHECK(dst.vb_int64 == -42);
303}
304
306{
307 fr_value_box_t src, dst;
308
309 fr_value_box(&src, (uint8_t) 255, false);
311
312 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT32, NULL, &src) == 0);
313 TEST_CHECK(dst.type == FR_TYPE_UINT32);
314 TEST_CHECK(dst.vb_uint32 == 255);
315}
316
317static void test_cast_same_type(void)
318{
319 fr_value_box_t src, dst;
320
321 fr_value_box(&src, (uint32_t) 42, false);
323
324 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT32, NULL, &src) == 0);
325 TEST_CHECK(dst.type == FR_TYPE_UINT32);
326 TEST_CHECK(dst.vb_uint32 == 42);
327}
328
330{
331 fr_value_box_t src, dst;
332
333 fr_value_box(&src, (bool) true, false);
335
336 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT32, NULL, &src) == 0);
337 TEST_CHECK(dst.vb_uint32 == 1);
338
339 fr_value_box(&src, (bool) false, false);
340 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_UINT32, NULL, &src) == 0);
341 TEST_CHECK(dst.vb_uint32 == 0);
342}
343
345{
346 fr_value_box_t src, dst;
347
348 fr_value_box(&src, (uint32_t) 1, false);
350
351 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_BOOL, NULL, &src) == 0);
352 TEST_CHECK(dst.vb_bool == true);
353
354 fr_value_box(&src, (uint32_t) 0, false);
355 TEST_CHECK(fr_value_box_cast(autofree, &dst, FR_TYPE_BOOL, NULL, &src) == 0);
356 TEST_CHECK(dst.vb_bool == false);
357}
358
359/*
360 * Cast in place tests
361 */
363{
365
366 fr_value_box(&vb, (uint32_t) 42, false);
367
369 TEST_CHECK(vb.type == FR_TYPE_UINT64);
370 TEST_CHECK(vb.vb_uint64 == 42);
371}
372
374{
376
377 fr_value_box(&vb, (uint32_t) 12345, false);
378
380 TEST_CHECK(vb.type == FR_TYPE_STRING);
381 TEST_CHECK_STRCMP(vb.vb_strvalue, "12345");
382
384}
385
386/*
387 * Copy tests
388 */
389static void test_copy_uint32(void)
390{
391 fr_value_box_t src, dst;
392
393 fr_value_box(&src, (uint32_t) 42, false);
395
396 TEST_CHECK(fr_value_box_copy(autofree, &dst, &src) == 0);
397 TEST_CHECK(dst.type == FR_TYPE_UINT32);
398 TEST_CHECK(dst.vb_uint32 == 42);
399}
400
401static void test_copy_string(void)
402{
403 fr_value_box_t src, dst;
404
405 fr_value_box_strdup(autofree, &src, NULL, "hello", false);
407
408 TEST_CHECK(fr_value_box_copy(autofree, &dst, &src) == 0);
409 TEST_CHECK(dst.type == FR_TYPE_STRING);
410 TEST_CHECK_STRCMP(dst.vb_strvalue, "hello");
411
412 /* Deep copy: different pointer */
413 TEST_CHECK(dst.vb_strvalue != src.vb_strvalue);
414
415 fr_value_box_clear(&src);
416 fr_value_box_clear(&dst);
417}
418
419static void test_copy_octets(void)
420{
421 fr_value_box_t src, dst;
422
423 fr_value_box_memdup(autofree, &src, NULL, (uint8_t const *)"\x01\x02\x03", 3, false);
425
426 TEST_CHECK(fr_value_box_copy(autofree, &dst, &src) == 0);
427 TEST_CHECK(dst.type == FR_TYPE_OCTETS);
428 TEST_CHECK(dst.vb_length == 3);
429 TEST_CHECK(memcmp(dst.vb_octets, "\x01\x02\x03", 3) == 0);
430
431 /* Deep copy */
432 TEST_CHECK(dst.vb_octets != src.vb_octets);
433
434 fr_value_box_clear(&src);
435 fr_value_box_clear(&dst);
436}
437
439{
440 fr_value_box_t src, dst;
441
442 fr_value_box(&src, (uint32_t) 42, true);
444
445 TEST_CHECK(fr_value_box_copy(autofree, &dst, &src) == 0);
446 TEST_CHECK(dst.tainted == true);
447}
448
449/*
450 * String operations
451 */
452static void test_strdup(void)
453{
455
456 TEST_CHECK(fr_value_box_strdup(autofree, &vb, NULL, "hello world", false) == 0);
457 TEST_CHECK(vb.type == FR_TYPE_STRING);
458 TEST_CHECK_STRCMP(vb.vb_strvalue, "hello world");
459 TEST_CHECK(vb.vb_length == 11);
460
462}
463
464static void test_asprintf(void)
465{
467
468 TEST_CHECK(fr_value_box_asprintf(autofree, &vb, NULL, false, "value=%d", 42) == 0);
469 TEST_CHECK(vb.type == FR_TYPE_STRING);
470 TEST_CHECK_STRCMP(vb.vb_strvalue, "value=42");
471
473}
474
475static void test_bstrndup(void)
476{
478
479 /* bstrndup copies exactly len bytes */
480 TEST_CHECK(fr_value_box_bstrndup(autofree, &vb, NULL, "hello\0world", 11, false) == 0);
481 TEST_CHECK(vb.type == FR_TYPE_STRING);
482 TEST_CHECK(vb.vb_length == 11);
483 TEST_CHECK(memcmp(vb.vb_strvalue, "hello\0world", 11) == 0);
484
486}
487
488/*
489 * Memory operations
490 */
491static void test_memdup(void)
492{
494 uint8_t data[] = { 0xde, 0xad, 0xbe, 0xef };
495
496 TEST_CHECK(fr_value_box_memdup(autofree, &vb, NULL, data, sizeof(data), false) == 0);
497 TEST_CHECK(vb.type == FR_TYPE_OCTETS);
498 TEST_CHECK(vb.vb_length == 4);
499 TEST_CHECK(memcmp(vb.vb_octets, data, 4) == 0);
500
502}
503
504/*
505 * Hash tests
506 */
507static void test_hash_same_values(void)
508{
509 fr_value_box_t a, b;
510
511 fr_value_box(&a, (uint32_t) 42, false);
512 fr_value_box(&b, (uint32_t) 42, false);
513
515}
516
518{
519 fr_value_box_t a, b;
520
521 fr_value_box(&a, (uint32_t) 42, false);
522 fr_value_box(&b, (uint32_t) 43, false);
523
525}
526
527static void test_hash_string(void)
528{
529 fr_value_box_t a, b;
530
531 fr_value_box_strdup(autofree, &a, NULL, "hello", false);
532 fr_value_box_strdup(autofree, &b, NULL, "hello", false);
533
535
538}
539
540/*
541 * Truthiness tests (fr_value_box_is_truthy)
542 */
543static void test_truthy_bool(void)
544{
546
547 fr_value_box(&vb, (bool) true, false);
549
550 fr_value_box(&vb, (bool) false, false);
551 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
552}
553
554static void test_truthy_uint32(void)
555{
557
558 fr_value_box(&vb, (uint32_t) 42, false);
560
561 fr_value_box(&vb, (uint32_t) 0, false);
562 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
563}
564
565static void test_truthy_string(void)
566{
568
569 fr_value_box_strdup(autofree, &vb, NULL, "hello", false);
572
573 fr_value_box_strdup(autofree, &vb, NULL, "", false);
574 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
576}
577
578static void test_truthy_octets(void)
579{
581
582 fr_value_box_memdup(autofree, &vb, NULL, (uint8_t const *)"\x01", 1, false);
585
586 fr_value_box_memdup(autofree, &vb, NULL, (uint8_t const *)"", 0, false);
587 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
589}
590
591/*
592 * Increment tests (fr_value_box_increment)
593 */
594static void test_increment_uint32(void)
595{
597
598 fr_value_box(&vb, (uint32_t) 41, false);
600 TEST_CHECK(vb.vb_uint32 == 42);
601 TEST_MSG("Expected 42, got %u", vb.vb_uint32);
602}
603
605{
607
608 fr_value_box(&vb, (uint8_t) UINT8_MAX, false);
610 TEST_CHECK(vb.vb_uint8 == 0);
611 TEST_MSG("Expected 0 (wrap), got %u", vb.vb_uint8);
612}
613
614static void test_increment_int32(void)
615{
617
618 fr_value_box(&vb, (int32_t) -1, false);
620 TEST_CHECK(vb.vb_int32 == 0);
621 TEST_MSG("Expected 0, got %d", vb.vb_int32);
622}
623
624/*
625 * as_uint64 extraction tests
626 */
627static void test_as_uint64(void)
628{
630
631 fr_value_box(&vb, (uint8_t) 255, false);
633
634 fr_value_box(&vb, (uint16_t) 1000, false);
636
637 fr_value_box(&vb, (uint32_t) 100000, false);
638 TEST_CHECK(fr_value_box_as_uint64(&vb) == 100000);
639
640 fr_value_box(&vb, (uint64_t) UINT64_MAX, false);
641 TEST_CHECK(fr_value_box_as_uint64(&vb) == UINT64_MAX);
642
643 fr_value_box(&vb, (bool) true, false);
645}
646
647/*
648 * Clear tests
649 */
650static void test_clear(void)
651{
653
654 fr_value_box(&vb, (uint32_t) 42, false);
655 TEST_CHECK(vb.type == FR_TYPE_UINT32);
656
658 TEST_CHECK(vb.type == FR_TYPE_NULL);
659}
660
661static void test_clear_string(void)
662{
664
665 fr_value_box_strdup(autofree, &vb, NULL, "hello", false);
666 TEST_CHECK(vb.type == FR_TYPE_STRING);
667
669 TEST_CHECK(vb.type == FR_TYPE_NULL);
670}
671
672/*
673 * Tainted flag tests
674 */
675static void test_tainted_flag(void)
676{
678
679 fr_value_box(&vb, (uint32_t) 42, true);
680 TEST_CHECK(vb.tainted == true);
681
682 fr_value_box(&vb, (uint32_t) 42, false);
683 TEST_CHECK(vb.tainted == false);
684}
685
686/*
687 * Network encode/decode round-trip tests
688 */
689static void test_network_uint32(void)
690{
691 fr_value_box_t src, dst;
692 uint8_t buffer[256] = {};
693 fr_dbuff_t dbuff;
694 ssize_t enc_len, dec_len;
695
696 fr_value_box(&src, (uint32_t) 0x12345678, false);
697
698 /* Encode to network format */
699 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
700 enc_len = fr_value_box_to_network(&dbuff, &src);
701 TEST_CHECK(enc_len == 4);
702
703 /* Verify network byte order (big endian) */
704 TEST_CHECK(buffer[0] == 0x12);
705 TEST_CHECK(buffer[1] == 0x34);
706 TEST_CHECK(buffer[2] == 0x56);
707 TEST_CHECK(buffer[3] == 0x78);
708
709 /* Decode back */
711 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
712 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_UINT32, NULL, &dbuff, enc_len, false);
713 TEST_CHECK(dec_len == 4);
714 TEST_CHECK(dst.vb_uint32 == 0x12345678);
715 TEST_MSG("Expected 0x12345678, got 0x%08x", dst.vb_uint32);
716}
717
718static void test_network_uint64(void)
719{
720 fr_value_box_t src, dst;
721 uint8_t buffer[256] = {};
722 fr_dbuff_t dbuff;
723 ssize_t enc_len, dec_len;
724
725 fr_value_box(&src, (uint64_t) 0x0102030405060708ULL, false);
726
727 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
728 enc_len = fr_value_box_to_network(&dbuff, &src);
729 TEST_CHECK(enc_len == 8);
730
731 /* Verify big endian */
732 TEST_CHECK(buffer[0] == 0x01);
733 TEST_CHECK(buffer[7] == 0x08);
734
735 /* Decode back */
737 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
738 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_UINT64, NULL, &dbuff, enc_len, false);
739 TEST_CHECK(dec_len == 8);
740 TEST_CHECK(dst.vb_uint64 == 0x0102030405060708ULL);
741}
742
743static void test_network_int32(void)
744{
745 fr_value_box_t src, dst;
746 uint8_t buffer[256] = {};
747 fr_dbuff_t dbuff;
748 ssize_t enc_len, dec_len;
749
750 fr_value_box(&src, (int32_t) -1, false);
751
752 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
753 enc_len = fr_value_box_to_network(&dbuff, &src);
754 TEST_CHECK(enc_len == 4);
755
756 /* -1 in two's complement big endian is 0xffffffff */
757 TEST_CHECK(buffer[0] == 0xff);
758 TEST_CHECK(buffer[1] == 0xff);
759 TEST_CHECK(buffer[2] == 0xff);
760 TEST_CHECK(buffer[3] == 0xff);
761
762 /* Decode back */
764 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
765 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_INT32, NULL, &dbuff, enc_len, false);
766 TEST_CHECK(dec_len == 4);
767 TEST_CHECK(dst.vb_int32 == -1);
768}
769
770static void test_network_bool(void)
771{
772 fr_value_box_t src, dst;
773 uint8_t buffer[256] = {};
774 fr_dbuff_t dbuff;
775 ssize_t enc_len, dec_len;
776
777 fr_value_box(&src, (bool) true, false);
778
779 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
780 enc_len = fr_value_box_to_network(&dbuff, &src);
781 TEST_CHECK(enc_len == 1);
782 TEST_CHECK(buffer[0] == 1);
783
785 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
786 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_BOOL, NULL, &dbuff, enc_len, false);
787 TEST_CHECK(dec_len == 1);
788 TEST_CHECK(dst.vb_bool == true);
789}
790
791static void test_network_length(void)
792{
794
795 fr_value_box(&vb, (uint8_t) 0, false);
797
798 fr_value_box(&vb, (uint16_t) 0, false);
800
801 fr_value_box(&vb, (uint32_t) 0, false);
803
804 fr_value_box(&vb, (uint64_t) 0, false);
806}
807
808/*
809 * Print tests (fr_value_box_print)
810 */
811static void test_print_uint32(void)
812{
814 char buffer[256] = {};
815 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
816
817 fr_value_box(&vb, (uint32_t) 42, false);
818
819 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
820 fr_sbuff_terminate(&sbuff);
822}
823
825{
827 char buffer[256] = {};
828 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
829
830 fr_value_box(&vb, (int32_t) -42, false);
831
832 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
833 fr_sbuff_terminate(&sbuff);
835}
836
837static void test_print_string(void)
838{
840 char buffer[256] = {};
841 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
842
843 fr_value_box_strdup(autofree, &vb, NULL, "hello", false);
844
845 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
846 fr_sbuff_terminate(&sbuff);
847 TEST_CHECK_STRCMP(buffer, "hello");
848
850}
851
852static void test_print_bool(void)
853{
855 char buffer[256] = {};
856 fr_sbuff_t sbuff;
857
858 fr_value_box(&vb, (bool) true, false);
859 sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
860 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
861 fr_sbuff_terminate(&sbuff);
863
864 fr_value_box(&vb, (bool) false, false);
865 sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
866 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
867 fr_sbuff_terminate(&sbuff);
869}
870
871static void test_print_octets(void)
872{
874 char buffer[256] = {};
875 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
876
877 fr_value_box_memdup(autofree, &vb, NULL, (uint8_t const *)"\xde\xad\xbe\xef", 4, false);
878
879 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
880 fr_sbuff_terminate(&sbuff);
881 TEST_CHECK_STRCMP(buffer, "0xdeadbeef");
882
884}
885
886/*
887 * From string parsing tests (fr_value_box_from_str)
888 */
889static void test_from_str_uint32(void)
890{
892
894 "12345", strlen("12345"), NULL) > 0);
895 TEST_CHECK(vb.type == FR_TYPE_UINT32);
896 TEST_CHECK(vb.vb_uint32 == 12345);
897 TEST_MSG("Expected 12345, got %u", vb.vb_uint32);
898}
899
900static void test_from_str_int32(void)
901{
903
905 "-42", strlen("-42"), NULL) > 0);
906 TEST_CHECK(vb.type == FR_TYPE_INT32);
907 TEST_CHECK(vb.vb_int32 == -42);
908 TEST_MSG("Expected -42, got %d", vb.vb_int32);
909}
910
911static void test_from_str_bool(void)
912{
914
916 "yes", strlen("yes"), NULL) > 0);
917 TEST_CHECK(vb.type == FR_TYPE_BOOL);
918 TEST_CHECK(vb.vb_bool == true);
919}
920
921static void test_from_str_float64(void)
922{
924
926 "3.14", strlen("3.14"), NULL) > 0);
927 TEST_CHECK(vb.type == FR_TYPE_FLOAT64);
928 TEST_CHECK((vb.vb_float64 > 3.13) && (vb.vb_float64 < 3.15));
929 TEST_MSG("Expected ~3.14, got %f", vb.vb_float64);
930}
931
932static void test_from_str_octets(void)
933{
935
937 "0xdeadbeef", strlen("0xdeadbeef"), NULL) > 0);
938 TEST_CHECK(vb.type == FR_TYPE_OCTETS);
939 TEST_CHECK(vb.vb_length == 4);
940 TEST_CHECK(memcmp(vb.vb_octets, "\xde\xad\xbe\xef", 4) == 0);
941
943}
944
945static void test_from_str_string(void)
946{
948
950 "hello world", strlen("hello world"), NULL) > 0);
951 TEST_CHECK(vb.type == FR_TYPE_STRING);
952 TEST_CHECK_STRCMP(vb.vb_strvalue, "hello world");
953
955}
956
957/*
958 * Print/parse round-trip tests
959 */
960static void test_round_trip_uint32(void)
961{
962 fr_value_box_t src, dst;
963 char buffer[256] = {};
964 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
965
966 fr_value_box(&src, (uint32_t) 42, false);
967
968 TEST_CHECK(fr_value_box_print(&sbuff, &src, NULL) > 0);
969 fr_sbuff_terminate(&sbuff);
970
972 buffer, strlen(buffer), NULL) > 0);
973 TEST_CHECK(dst.vb_uint32 == 42);
974}
975
976static void test_round_trip_int64(void)
977{
978 fr_value_box_t src, dst;
979 char buffer[256] = {};
980 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
981
982 fr_value_box(&src, (int64_t) -9999999, false);
983
984 TEST_CHECK(fr_value_box_print(&sbuff, &src, NULL) > 0);
985 fr_sbuff_terminate(&sbuff);
986
988 buffer, strlen(buffer), NULL) > 0);
989 TEST_CHECK(dst.vb_int64 == -9999999);
990}
991
992static void test_round_trip_bool(void)
993{
994 fr_value_box_t src, dst;
995 char buffer[256] = {};
996 fr_sbuff_t sbuff;
997
998 fr_value_box(&src, (bool) true, false);
999 sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1000 TEST_CHECK(fr_value_box_print(&sbuff, &src, NULL) > 0);
1001 fr_sbuff_terminate(&sbuff);
1002
1004 buffer, strlen(buffer), NULL) > 0);
1005 TEST_CHECK(dst.vb_bool == true);
1006}
1007
1009{
1010 fr_value_box_t src, dst;
1011 uint8_t buffer[256] = {};
1012 fr_dbuff_t dbuff;
1013 ssize_t enc_len;
1014
1015 fr_value_box(&src, (uint32_t) 0xdeadbeef, false);
1016
1017 /* Encode */
1018 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
1019 enc_len = fr_value_box_to_network(&dbuff, &src);
1020 TEST_CHECK(enc_len == 4);
1021
1022 /* Decode */
1024 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
1025 TEST_CHECK(fr_value_box_from_network(NULL, &dst, FR_TYPE_UINT32, NULL, &dbuff, enc_len, false) == 4);
1026 TEST_CHECK(dst.vb_uint32 == 0xdeadbeef);
1027}
1028
1030 /* Comparison tests */
1031 { "cmp_uint32_equal", test_cmp_uint32_equal },
1032 { "cmp_uint32_less", test_cmp_uint32_less },
1033 { "cmp_int32", test_cmp_int32 },
1034 { "cmp_float64", test_cmp_float64 },
1035 { "cmp_string", test_cmp_string },
1036 { "cmp_octets", test_cmp_octets },
1037 { "cmp_octets_length", test_cmp_octets_length },
1038 { "cmp_bool", test_cmp_bool },
1039 { "cmp_different_types", test_cmp_different_types },
1040
1041 /* Comparison operator tests */
1042 { "cmp_op_eq", test_cmp_op_eq },
1043 { "cmp_op_ne", test_cmp_op_ne },
1044 { "cmp_op_lt", test_cmp_op_lt },
1045 { "cmp_op_gt", test_cmp_op_gt },
1046 { "cmp_op_le", test_cmp_op_le },
1047 { "cmp_op_ge", test_cmp_op_ge },
1048
1049 /* Cast tests */
1050 { "cast_uint32_to_uint64", test_cast_uint32_to_uint64 },
1051 { "cast_uint32_to_string", test_cast_uint32_to_string },
1052 { "cast_string_to_uint32", test_cast_string_to_uint32 },
1053 { "cast_int32_to_int64", test_cast_int32_to_int64 },
1054 { "cast_uint8_to_uint32", test_cast_uint8_to_uint32 },
1055 { "cast_same_type", test_cast_same_type },
1056 { "cast_bool_to_uint32", test_cast_bool_to_uint32 },
1057 { "cast_uint32_to_bool", test_cast_uint32_to_bool },
1058
1059 /* Cast in place */
1060 { "cast_in_place_uint32_to_uint64", test_cast_in_place_uint32_to_uint64 },
1061 { "cast_in_place_uint32_to_string", test_cast_in_place_uint32_to_string },
1062
1063 /* Copy tests */
1064 { "copy_uint32", test_copy_uint32 },
1065 { "copy_string", test_copy_string },
1066 { "copy_octets", test_copy_octets },
1067 { "copy_preserves_tainted", test_copy_preserves_tainted },
1068
1069 /* String operations */
1070 { "strdup", test_strdup },
1071 { "asprintf", test_asprintf },
1072 { "bstrndup", test_bstrndup },
1073
1074 /* Memory operations */
1075 { "memdup", test_memdup },
1076
1077 /* Hash tests */
1078 { "hash_same_values", test_hash_same_values },
1079 { "hash_different_values", test_hash_different_values },
1080 { "hash_string", test_hash_string },
1081
1082 /* Truthiness tests */
1083 { "truthy_bool", test_truthy_bool },
1084 { "truthy_uint32", test_truthy_uint32 },
1085 { "truthy_string", test_truthy_string },
1086 { "truthy_octets", test_truthy_octets },
1087
1088 /* Increment tests */
1089 { "increment_uint32", test_increment_uint32 },
1090 { "increment_uint8_overflow", test_increment_uint8_overflow },
1091 { "increment_int32", test_increment_int32 },
1092
1093 /* as_uint64 */
1094 { "as_uint64", test_as_uint64 },
1095
1096 /* Clear tests */
1097 { "clear", test_clear },
1098 { "clear_string", test_clear_string },
1099
1100 /* Tainted flag */
1101 { "tainted_flag", test_tainted_flag },
1102
1103 /* Network encode/decode */
1104 { "network_uint32", test_network_uint32 },
1105 { "network_uint64", test_network_uint64 },
1106 { "network_int32", test_network_int32 },
1107 { "network_bool", test_network_bool },
1108 { "network_length", test_network_length },
1109
1110 /* Print tests */
1111 { "print_uint32", test_print_uint32 },
1112 { "print_int32_negative", test_print_int32_negative },
1113 { "print_string", test_print_string },
1114 { "print_bool", test_print_bool },
1115 { "print_octets", test_print_octets },
1116
1117 /* From string parsing */
1118 { "from_str_uint32", test_from_str_uint32 },
1119 { "from_str_int32", test_from_str_int32 },
1120 { "from_str_bool", test_from_str_bool },
1121 { "from_str_float64", test_from_str_float64 },
1122 { "from_str_octets", test_from_str_octets },
1123 { "from_str_string", test_from_str_string },
1124
1125 /* Round-trip tests */
1126 { "round_trip_uint32", test_round_trip_uint32 },
1127 { "round_trip_int64", test_round_trip_int64 },
1128 { "round_trip_bool", test_round_trip_bool },
1129 { "round_trip_network_uint32", test_round_trip_network_uint32 },
1130
1132};
static int const char char buffer[256]
Definition acutest.h:578
#define TEST_CHECK(cond)
Definition acutest.h:87
#define TEST_TERMINATOR
Definition acutest.h:64
#define TEST_MSG(...)
Definition acutest.h:217
#define TEST_CHECK_STRCMP(_got, _exp)
#define FR_DBUFF_TMP(_start, _len_or_end)
Creates a compound literal to pass into functions which accept a dbuff.
Definition dbuff.h:524
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition debug.h:226
unsigned short uint16_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_FLOAT64
Double precision floating point.
unsigned int uint32_t
long int ssize_t
unsigned char uint8_t
#define UINT8_MAX
#define FR_SBUFF_OUT(_start, _len_or_end)
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition talloc.h:51
@ T_OP_NE
Definition token.h:97
@ T_OP_CMP_EQ
Definition token.h:106
@ T_OP_LE
Definition token.h:100
@ T_OP_GE
Definition token.h:98
@ T_OP_GT
Definition token.h:99
@ T_OP_LT
Definition token.h:101
void fr_perror(char const *fmt,...)
Print the current error to stderr with a prefix.
Definition strerror.c:732
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
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:1439
uint32_t fr_value_box_hash(fr_value_box_t const *vb)
Hash the contents of a value box.
Definition value.c:7099
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:6116
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:1922
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:3961
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:4722
int8_t fr_value_box_cmp(fr_value_box_t const *a, fr_value_box_t const *b)
Compare two values.
Definition value.c:749
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:4409
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:1023
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:4261
bool fr_value_box_is_truthy(fr_value_box_t const *in)
Check truthiness of values.
Definition value.c:7401
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:4211
ssize_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:6079
void fr_value_box_increment(fr_value_box_t *vb)
Increment a boxed value.
Definition value.c:5270
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:4634
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
Definition value.c:4392
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:1525
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:4853
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:5094
static fr_slen_t data
Definition value.h:1340
#define fr_value_box_init_null(_vb)
Initialise an empty/null box that will be filled later.
Definition value.h:616
#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:904
static void test_clear(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)
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_cmp_octets_length(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_cast_uint32_to_string(void)
static void test_bstrndup(void)
static void test_print_int32_negative(void)
static void test_increment_uint32(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_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_cmp_op_lt(void)
static void test_cast_same_type(void)
static void test_cmp_octets(void)
static void test_cast_bool_to_uint32(void)
static void test_from_str_bool(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_cmp_string(void)
Definition value_tests.c:97
static void test_hash_same_values(void)
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 test_print_bool(void)
static void test_truthy_string(void)
static void test_cmp_bool(void)
static void test_cmp_uint32_less(void)
Definition value_tests.c:58
static void test_copy_octets(void)
static void test_from_str_uint32(void)
static void test_network_bool(void)