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.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 * String operations
452 */
453static void test_strdup(void)
454{
456
457 TEST_CHECK(fr_value_box_strdup(autofree, &vb, NULL, "hello world", false) == 0);
458 TEST_CHECK(vb.type == FR_TYPE_STRING);
459 TEST_CHECK_STRCMP(vb.vb_strvalue, "hello world");
460 TEST_CHECK(vb.vb_length == 11);
461
463}
464
465static void test_asprintf(void)
466{
468
469 TEST_CHECK(fr_value_box_asprintf(autofree, &vb, NULL, false, "value=%d", 42) == 0);
470 TEST_CHECK(vb.type == FR_TYPE_STRING);
471 TEST_CHECK_STRCMP(vb.vb_strvalue, "value=42");
472
474}
475
476static void test_bstrndup(void)
477{
479
480 /* bstrndup copies exactly len bytes */
481 TEST_CHECK(fr_value_box_bstrndup(autofree, &vb, NULL, "hello\0world", 11, false) == 0);
482 TEST_CHECK(vb.type == FR_TYPE_STRING);
483 TEST_CHECK(vb.vb_length == 11);
484 TEST_CHECK(memcmp(vb.vb_strvalue, "hello\0world", 11) == 0);
485
487}
488
489/*
490 * Memory operations
491 */
492static void test_memdup(void)
493{
495 uint8_t data[] = { 0xde, 0xad, 0xbe, 0xef };
496
497 TEST_CHECK(fr_value_box_memdup(autofree, &vb, NULL, data, sizeof(data), false) == 0);
498 TEST_CHECK(vb.type == FR_TYPE_OCTETS);
499 TEST_CHECK(vb.vb_length == 4);
500 TEST_CHECK(memcmp(vb.vb_octets, data, 4) == 0);
501
503}
504
505/*
506 * Hash tests
507 */
508static void test_hash_same_values(void)
509{
510 fr_value_box_t a, b;
511
512 fr_value_box(&a, (uint32_t) 42, false);
513 fr_value_box(&b, (uint32_t) 42, false);
514
516}
517
519{
520 fr_value_box_t a, b;
521
522 fr_value_box(&a, (uint32_t) 42, false);
523 fr_value_box(&b, (uint32_t) 43, false);
524
526}
527
528static void test_hash_string(void)
529{
530 fr_value_box_t a, b;
531
532 fr_value_box_strdup(autofree, &a, NULL, "hello", false);
533 fr_value_box_strdup(autofree, &b, NULL, "hello", false);
534
536
539}
540
541/*
542 * Truthiness tests (fr_value_box_is_truthy)
543 */
544static void test_truthy_bool(void)
545{
547
548 fr_value_box(&vb, (bool) true, false);
550
551 fr_value_box(&vb, (bool) false, false);
552 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
553}
554
555static void test_truthy_uint32(void)
556{
558
559 fr_value_box(&vb, (uint32_t) 42, false);
561
562 fr_value_box(&vb, (uint32_t) 0, false);
563 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
564}
565
566static void test_truthy_string(void)
567{
569
570 fr_value_box_strdup(autofree, &vb, NULL, "hello", false);
573
574 fr_value_box_strdup(autofree, &vb, NULL, "", false);
575 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
577}
578
579static void test_truthy_octets(void)
580{
582
583 fr_value_box_memdup(autofree, &vb, NULL, (uint8_t const *)"\x01", 1, false);
586
587 fr_value_box_memdup(autofree, &vb, NULL, (uint8_t const *)"", 0, false);
588 TEST_CHECK(fr_value_box_is_truthy(&vb) == false);
590}
591
592/*
593 * Increment tests (fr_value_box_increment)
594 */
595static void test_increment_uint32(void)
596{
598
599 fr_value_box(&vb, (uint32_t) 41, false);
601 TEST_CHECK(vb.vb_uint32 == 42);
602 TEST_MSG("Expected 42, got %u", vb.vb_uint32);
603}
604
606{
608
609 fr_value_box(&vb, (uint8_t) UINT8_MAX, false);
611 TEST_CHECK(vb.vb_uint8 == 0);
612 TEST_MSG("Expected 0 (wrap), got %u", vb.vb_uint8);
613}
614
615static void test_increment_int32(void)
616{
618
619 fr_value_box(&vb, (int32_t) -1, false);
621 TEST_CHECK(vb.vb_int32 == 0);
622 TEST_MSG("Expected 0, got %d", vb.vb_int32);
623}
624
625/*
626 * as_uint64 extraction tests
627 */
628static void test_as_uint64(void)
629{
631
632 fr_value_box(&vb, (uint8_t) 255, false);
634
635 fr_value_box(&vb, (uint16_t) 1000, false);
637
638 fr_value_box(&vb, (uint32_t) 100000, false);
639 TEST_CHECK(fr_value_box_as_uint64(&vb) == 100000);
640
641 fr_value_box(&vb, (uint64_t) UINT64_MAX, false);
642 TEST_CHECK(fr_value_box_as_uint64(&vb) == UINT64_MAX);
643
644 fr_value_box(&vb, (bool) true, false);
646}
647
648/*
649 * Clear tests
650 */
651static void test_clear(void)
652{
654
655 fr_value_box(&vb, (uint32_t) 42, false);
656 TEST_CHECK(vb.type == FR_TYPE_UINT32);
657
659 TEST_CHECK(vb.type == FR_TYPE_NULL);
660}
661
662static void test_clear_string(void)
663{
665
666 fr_value_box_strdup(autofree, &vb, NULL, "hello", false);
667 TEST_CHECK(vb.type == FR_TYPE_STRING);
668
670 TEST_CHECK(vb.type == FR_TYPE_NULL);
671}
672
673/*
674 * Tainted flag tests
675 */
676static void test_tainted_flag(void)
677{
679
680 fr_value_box(&vb, (uint32_t) 42, true);
681 TEST_CHECK(vb.tainted == true);
682
683 fr_value_box(&vb, (uint32_t) 42, false);
684 TEST_CHECK(vb.tainted == false);
685}
686
687/*
688 * Network encode/decode round-trip tests
689 */
690static void test_network_uint32(void)
691{
692 fr_value_box_t src, dst;
693 uint8_t buffer[256] = {};
694 fr_dbuff_t dbuff;
695 ssize_t enc_len, dec_len;
696
697 fr_value_box(&src, (uint32_t) 0x12345678, false);
698
699 /* Encode to network format */
700 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
701 enc_len = fr_value_box_to_network(&dbuff, &src);
702 TEST_CHECK(enc_len == 4);
703
704 /* Verify network byte order (big endian) */
705 TEST_CHECK(buffer[0] == 0x12);
706 TEST_CHECK(buffer[1] == 0x34);
707 TEST_CHECK(buffer[2] == 0x56);
708 TEST_CHECK(buffer[3] == 0x78);
709
710 /* Decode back */
712 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
713 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_UINT32, NULL, &dbuff, enc_len, false);
714 TEST_CHECK(dec_len == 4);
715 TEST_CHECK(dst.vb_uint32 == 0x12345678);
716 TEST_MSG("Expected 0x12345678, got 0x%08x", dst.vb_uint32);
717}
718
719static void test_network_uint64(void)
720{
721 fr_value_box_t src, dst;
722 uint8_t buffer[256] = {};
723 fr_dbuff_t dbuff;
724 ssize_t enc_len, dec_len;
725
726 fr_value_box(&src, (uint64_t) 0x0102030405060708ULL, false);
727
728 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
729 enc_len = fr_value_box_to_network(&dbuff, &src);
730 TEST_CHECK(enc_len == 8);
731
732 /* Verify big endian */
733 TEST_CHECK(buffer[0] == 0x01);
734 TEST_CHECK(buffer[7] == 0x08);
735
736 /* Decode back */
738 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
739 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_UINT64, NULL, &dbuff, enc_len, false);
740 TEST_CHECK(dec_len == 8);
741 TEST_CHECK(dst.vb_uint64 == 0x0102030405060708ULL);
742}
743
744static void test_network_int32(void)
745{
746 fr_value_box_t src, dst;
747 uint8_t buffer[256] = {};
748 fr_dbuff_t dbuff;
749 ssize_t enc_len, dec_len;
750
751 fr_value_box(&src, (int32_t) -1, false);
752
753 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
754 enc_len = fr_value_box_to_network(&dbuff, &src);
755 TEST_CHECK(enc_len == 4);
756
757 /* -1 in two's complement big endian is 0xffffffff */
758 TEST_CHECK(buffer[0] == 0xff);
759 TEST_CHECK(buffer[1] == 0xff);
760 TEST_CHECK(buffer[2] == 0xff);
761 TEST_CHECK(buffer[3] == 0xff);
762
763 /* Decode back */
765 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
766 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_INT32, NULL, &dbuff, enc_len, false);
767 TEST_CHECK(dec_len == 4);
768 TEST_CHECK(dst.vb_int32 == -1);
769}
770
771static void test_network_bool(void)
772{
773 fr_value_box_t src, dst;
774 uint8_t buffer[256] = {};
775 fr_dbuff_t dbuff;
776 ssize_t enc_len, dec_len;
777
778 fr_value_box(&src, (bool) true, false);
779
780 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
781 enc_len = fr_value_box_to_network(&dbuff, &src);
782 TEST_CHECK(enc_len == 1);
783 TEST_CHECK(buffer[0] == 1);
784
786 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
787 dec_len = fr_value_box_from_network(NULL, &dst, FR_TYPE_BOOL, NULL, &dbuff, enc_len, false);
788 TEST_CHECK(dec_len == 1);
789 TEST_CHECK(dst.vb_bool == true);
790}
791
792static void test_network_length(void)
793{
795
796 fr_value_box(&vb, (uint8_t) 0, false);
798
799 fr_value_box(&vb, (uint16_t) 0, false);
801
802 fr_value_box(&vb, (uint32_t) 0, false);
804
805 fr_value_box(&vb, (uint64_t) 0, false);
807}
808
809/*
810 * Print tests (fr_value_box_print)
811 */
812static void test_print_uint32(void)
813{
815 char buffer[256] = {};
816 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
817
818 fr_value_box(&vb, (uint32_t) 42, false);
819
820 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
821 fr_sbuff_terminate(&sbuff);
823}
824
826{
828 char buffer[256] = {};
829 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
830
831 fr_value_box(&vb, (int32_t) -42, false);
832
833 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
834 fr_sbuff_terminate(&sbuff);
836}
837
838static void test_print_string(void)
839{
841 char buffer[256] = {};
842 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
843
844 fr_value_box_strdup(autofree, &vb, NULL, "hello", false);
845
846 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
847 fr_sbuff_terminate(&sbuff);
848 TEST_CHECK_STRCMP(buffer, "hello");
849
851}
852
853static void test_print_bool(void)
854{
856 char buffer[256] = {};
857 fr_sbuff_t sbuff;
858
859 fr_value_box(&vb, (bool) true, false);
860 sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
861 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
862 fr_sbuff_terminate(&sbuff);
864
865 fr_value_box(&vb, (bool) false, false);
866 sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
867 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
868 fr_sbuff_terminate(&sbuff);
870}
871
872static void test_print_octets(void)
873{
875 char buffer[256] = {};
876 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
877
878 fr_value_box_memdup(autofree, &vb, NULL, (uint8_t const *)"\xde\xad\xbe\xef", 4, false);
879
880 TEST_CHECK(fr_value_box_print(&sbuff, &vb, NULL) > 0);
881 fr_sbuff_terminate(&sbuff);
882 TEST_CHECK_STRCMP(buffer, "0xdeadbeef");
883
885}
886
887/*
888 * From string parsing tests (fr_value_box_from_str)
889 */
890static void test_from_str_uint32(void)
891{
893
895 "12345", strlen("12345"), NULL) > 0);
896 TEST_CHECK(vb.type == FR_TYPE_UINT32);
897 TEST_CHECK(vb.vb_uint32 == 12345);
898 TEST_MSG("Expected 12345, got %u", vb.vb_uint32);
899}
900
901static void test_from_str_int32(void)
902{
904
906 "-42", strlen("-42"), NULL) > 0);
907 TEST_CHECK(vb.type == FR_TYPE_INT32);
908 TEST_CHECK(vb.vb_int32 == -42);
909 TEST_MSG("Expected -42, got %d", vb.vb_int32);
910}
911
912static void test_from_str_bool(void)
913{
915
917 "yes", strlen("yes"), NULL) > 0);
918 TEST_CHECK(vb.type == FR_TYPE_BOOL);
919 TEST_CHECK(vb.vb_bool == true);
920}
921
922static void test_from_str_float64(void)
923{
925
927 "3.14", strlen("3.14"), NULL) > 0);
928 TEST_CHECK(vb.type == FR_TYPE_FLOAT64);
929 TEST_CHECK((vb.vb_float64 > 3.13) && (vb.vb_float64 < 3.15));
930 TEST_MSG("Expected ~3.14, got %f", vb.vb_float64);
931}
932
933static void test_from_str_octets(void)
934{
936
938 "0xdeadbeef", strlen("0xdeadbeef"), NULL) > 0);
939 TEST_CHECK(vb.type == FR_TYPE_OCTETS);
940 TEST_CHECK(vb.vb_length == 4);
941 TEST_CHECK(memcmp(vb.vb_octets, "\xde\xad\xbe\xef", 4) == 0);
942
944}
945
946static void test_from_str_string(void)
947{
949
951 "hello world", strlen("hello world"), NULL) > 0);
952 TEST_CHECK(vb.type == FR_TYPE_STRING);
953 TEST_CHECK_STRCMP(vb.vb_strvalue, "hello world");
954
956}
957
958/*
959 * Print/parse round-trip tests
960 */
961static void test_round_trip_uint32(void)
962{
963 fr_value_box_t src, dst;
964 char buffer[256] = {};
965 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
966
967 fr_value_box(&src, (uint32_t) 42, false);
968
969 TEST_CHECK(fr_value_box_print(&sbuff, &src, NULL) > 0);
970 fr_sbuff_terminate(&sbuff);
971
973 buffer, strlen(buffer), NULL) > 0);
974 TEST_CHECK(dst.vb_uint32 == 42);
975}
976
977static void test_round_trip_int64(void)
978{
979 fr_value_box_t src, dst;
980 char buffer[256] = {};
981 fr_sbuff_t sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
982
983 fr_value_box(&src, (int64_t) -9999999, false);
984
985 TEST_CHECK(fr_value_box_print(&sbuff, &src, NULL) > 0);
986 fr_sbuff_terminate(&sbuff);
987
989 buffer, strlen(buffer), NULL) > 0);
990 TEST_CHECK(dst.vb_int64 == -9999999);
991}
992
993static void test_round_trip_bool(void)
994{
995 fr_value_box_t src, dst;
996 char buffer[256] = {};
997 fr_sbuff_t sbuff;
998
999 fr_value_box(&src, (bool) true, false);
1000 sbuff = FR_SBUFF_OUT(buffer, sizeof(buffer));
1001 TEST_CHECK(fr_value_box_print(&sbuff, &src, NULL) > 0);
1002 fr_sbuff_terminate(&sbuff);
1003
1005 buffer, strlen(buffer), NULL) > 0);
1006 TEST_CHECK(dst.vb_bool == true);
1007}
1008
1010{
1011 fr_value_box_t src, dst;
1012 uint8_t buffer[256] = {};
1013 fr_dbuff_t dbuff;
1014 ssize_t enc_len;
1015
1016 fr_value_box(&src, (uint32_t) 0xdeadbeef, false);
1017
1018 /* Encode */
1019 dbuff = FR_DBUFF_TMP(buffer, sizeof(buffer));
1020 enc_len = fr_value_box_to_network(&dbuff, &src);
1021 TEST_CHECK(enc_len == 4);
1022
1023 /* Decode */
1025 dbuff = FR_DBUFF_TMP(buffer, (size_t)enc_len);
1026 TEST_CHECK(fr_value_box_from_network(NULL, &dst, FR_TYPE_UINT32, NULL, &dbuff, enc_len, false) == 4);
1027 TEST_CHECK(dst.vb_uint32 == 0xdeadbeef);
1028}
1029
1031 /* Comparison tests */
1032 { "cmp_uint32_equal", test_cmp_uint32_equal },
1033 { "cmp_uint32_less", test_cmp_uint32_less },
1034 { "cmp_int32", test_cmp_int32 },
1035 { "cmp_float64", test_cmp_float64 },
1036 { "cmp_string", test_cmp_string },
1037 { "cmp_octets", test_cmp_octets },
1038 { "cmp_octets_length", test_cmp_octets_length },
1039 { "cmp_bool", test_cmp_bool },
1040 { "cmp_different_types", test_cmp_different_types },
1041
1042 /* Comparison operator tests */
1043 { "cmp_op_eq", test_cmp_op_eq },
1044 { "cmp_op_ne", test_cmp_op_ne },
1045 { "cmp_op_lt", test_cmp_op_lt },
1046 { "cmp_op_gt", test_cmp_op_gt },
1047 { "cmp_op_le", test_cmp_op_le },
1048 { "cmp_op_ge", test_cmp_op_ge },
1049
1050 /* Cast tests */
1051 { "cast_uint32_to_uint64", test_cast_uint32_to_uint64 },
1052 { "cast_uint32_to_string", test_cast_uint32_to_string },
1053 { "cast_string_to_uint32", test_cast_string_to_uint32 },
1054 { "cast_int32_to_int64", test_cast_int32_to_int64 },
1055 { "cast_uint8_to_uint32", test_cast_uint8_to_uint32 },
1056 { "cast_same_type", test_cast_same_type },
1057 { "cast_bool_to_uint32", test_cast_bool_to_uint32 },
1058 { "cast_uint32_to_bool", test_cast_uint32_to_bool },
1059
1060 /* Cast in place */
1061 { "cast_in_place_uint32_to_uint64", test_cast_in_place_uint32_to_uint64 },
1062 { "cast_in_place_uint32_to_string", test_cast_in_place_uint32_to_string },
1063
1064 /* Copy tests */
1065 { "copy_uint32", test_copy_uint32 },
1066 { "copy_string", test_copy_string },
1067 { "copy_octets", test_copy_octets },
1068 { "copy_preserves_tainted", test_copy_preserves_tainted },
1069
1070 /* String operations */
1071 { "strdup", test_strdup },
1072 { "asprintf", test_asprintf },
1073 { "bstrndup", test_bstrndup },
1074
1075 /* Memory operations */
1076 { "memdup", test_memdup },
1077
1078 /* Hash tests */
1079 { "hash_same_values", test_hash_same_values },
1080 { "hash_different_values", test_hash_different_values },
1081 { "hash_string", test_hash_string },
1082
1083 /* Truthiness tests */
1084 { "truthy_bool", test_truthy_bool },
1085 { "truthy_uint32", test_truthy_uint32 },
1086 { "truthy_string", test_truthy_string },
1087 { "truthy_octets", test_truthy_octets },
1088
1089 /* Increment tests */
1090 { "increment_uint32", test_increment_uint32 },
1091 { "increment_uint8_overflow", test_increment_uint8_overflow },
1092 { "increment_int32", test_increment_int32 },
1093
1094 /* as_uint64 */
1095 { "as_uint64", test_as_uint64 },
1096
1097 /* Clear tests */
1098 { "clear", test_clear },
1099 { "clear_string", test_clear_string },
1100
1101 /* Tainted flag */
1102 { "tainted_flag", test_tainted_flag },
1103
1104 /* Network encode/decode */
1105 { "network_uint32", test_network_uint32 },
1106 { "network_uint64", test_network_uint64 },
1107 { "network_int32", test_network_int32 },
1108 { "network_bool", test_network_bool },
1109 { "network_length", test_network_length },
1110
1111 /* Print tests */
1112 { "print_uint32", test_print_uint32 },
1113 { "print_int32_negative", test_print_int32_negative },
1114 { "print_string", test_print_string },
1115 { "print_bool", test_print_bool },
1116 { "print_octets", test_print_octets },
1117
1118 /* From string parsing */
1119 { "from_str_uint32", test_from_str_uint32 },
1120 { "from_str_int32", test_from_str_int32 },
1121 { "from_str_bool", test_from_str_bool },
1122 { "from_str_float64", test_from_str_float64 },
1123 { "from_str_octets", test_from_str_octets },
1124 { "from_str_string", test_from_str_string },
1125
1126 /* Round-trip tests */
1127 { "round_trip_uint32", test_round_trip_uint32 },
1128 { "round_trip_int64", test_round_trip_int64 },
1129 { "round_trip_bool", test_round_trip_bool },
1130 { "round_trip_network_uint32", test_round_trip_network_uint32 },
1131
1133};
static int const char char buffer[256]
Definition acutest.h:576
#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:522
#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
@ CMP_ERR
comparison failed
Definition misc.h:51
#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: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
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:759
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:1423
uint32_t fr_value_box_hash(fr_value_box_t const *vb)
Hash the contents of a value box.
Definition value.c:7114
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:6131
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:1906
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:3968
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:4731
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:4416
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:1006
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:4268
bool fr_value_box_is_truthy(fr_value_box_t const *in)
Check truthiness of values.
Definition value.c:7421
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:4218
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:6094
void fr_value_box_increment(fr_value_box_t *vb)
Increment a boxed value.
Definition value.c:5279
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:4643
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
Definition value.c:4399
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:1509
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:4862
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:5103
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)