The FreeRADIUS server $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Loading...
Searching...
No Matches
calc_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 calculation functions
18 *
19 * @file src/lib/util/test/calc_tests.c
20 * @copyright 2021 Network RADIUS SAS (legal@networkradius.com)
21 */
22
23#include "acutest.h"
24#include "acutest_helpers.h"
25
26#include <freeradius-devel/util/calc.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("calc_tests");
36 fr_exit_now(EXIT_FAILURE);
37 }
38
40 fr_perror("calc_tests");
41 fr_exit_now(EXIT_FAILURE);
42 }
43}
44
45/*
46 * uint64 arithmetic
47 */
48static void test_uint32_add(void)
49{
50 fr_value_box_t a, b, dst;
51
52 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
53
54 fr_value_box(&a, (uint32_t) 10, false);
55 fr_value_box(&b, (uint32_t) 20, false);
56
58 TEST_CHECK(dst.vb_uint32 == 30);
59 TEST_MSG("Expected 30, got %u", dst.vb_uint32);
60}
61
62static void test_uint32_sub(void)
63{
64 fr_value_box_t a, b, dst;
65
66 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
67
68 fr_value_box(&a, (uint32_t) 30, false);
69 fr_value_box(&b, (uint32_t) 10, false);
70
72 TEST_CHECK(dst.vb_uint32 == 20);
73 TEST_MSG("Expected 20, got %u", dst.vb_uint32);
74}
75
76static void test_uint32_mul(void)
77{
78 fr_value_box_t a, b, dst;
79
80 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
81
82 fr_value_box(&a, (uint32_t) 6, false);
83 fr_value_box(&b, (uint32_t) 7, false);
84
86 TEST_CHECK(dst.vb_uint32 == 42);
87 TEST_MSG("Expected 42, got %u", dst.vb_uint32);
88}
89
90static void test_uint32_div(void)
91{
92 fr_value_box_t a, b, dst;
93
94 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
95
96 fr_value_box(&a, (uint32_t) 42, false);
97 fr_value_box(&b, (uint32_t) 6, false);
98
100 TEST_CHECK(dst.vb_uint32 == 7);
101 TEST_MSG("Expected 7, got %u", dst.vb_uint32);
102}
103
104static void test_uint32_mod(void)
105{
106 fr_value_box_t a, b, dst;
107
108 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
109
110 fr_value_box(&a, (uint32_t) 17, false);
111 fr_value_box(&b, (uint32_t) 5, false);
112
114 TEST_CHECK(dst.vb_uint32 == 2);
115 TEST_MSG("Expected 2, got %u", dst.vb_uint32);
116}
117
118static void test_uint32_and(void)
119{
120 fr_value_box_t a, b, dst;
121
122 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
123
124 fr_value_box(&a, (uint32_t) 0xff, false);
125 fr_value_box(&b, (uint32_t) 0x0f, false);
126
128 TEST_CHECK(dst.vb_uint32 == 0x0f);
129 TEST_MSG("Expected 0x0f, got 0x%x", dst.vb_uint32);
130}
131
132static void test_uint32_or(void)
133{
134 fr_value_box_t a, b, dst;
135
136 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
137
138 fr_value_box(&a, (uint32_t) 0xf0, false);
139 fr_value_box(&b, (uint32_t) 0x0f, false);
140
142 TEST_CHECK(dst.vb_uint32 == 0xff);
143 TEST_MSG("Expected 0xff, got 0x%x", dst.vb_uint32);
144}
145
146static void test_uint32_xor(void)
147{
148 fr_value_box_t a, b, dst;
149
150 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
151
152 fr_value_box(&a, (uint32_t) 0xff, false);
153 fr_value_box(&b, (uint32_t) 0x0f, false);
154
156 TEST_CHECK(dst.vb_uint32 == 0xf0);
157 TEST_MSG("Expected 0xf0, got 0x%x", dst.vb_uint32);
158}
159
160static void test_uint32_shift(void)
161{
162 fr_value_box_t a, b, dst;
163
164
165 fr_value_box(&a, (uint32_t) 0x10, false);
166 fr_value_box(&b, (uint32_t) 4, false);
167
168 /* left shift */
169 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
171 TEST_CHECK(dst.vb_uint64 == 0x100);
172 TEST_MSG("Expected 0x100, got 0x%" PRIx64, dst.vb_uint64);
173
174 /* right shift */
175 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
177 TEST_CHECK(dst.vb_uint32 == 0x01);
178 TEST_MSG("Expected 0x01, got 0x%x", dst.vb_uint32);
179}
180
181/*
182 * Division by zero
183 */
184static void test_uint32_div_zero(void)
185{
186 fr_value_box_t a, b, dst;
187
188 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
189
190 fr_value_box(&a, (uint32_t) 42, false);
191 fr_value_box(&b, (uint32_t) 0, false);
192
194
196}
197
198/*
199 * uint8 tests - verify smaller int types work via calc_uint64 upcast
200 */
201static void test_uint8_add(void)
202{
203 fr_value_box_t a, b, dst;
204
205 fr_value_box_init(&dst, FR_TYPE_UINT8, NULL, false);
206
207 fr_value_box(&a, (uint8_t) 100, false);
208 fr_value_box(&b, (uint8_t) 50, false);
209
211 TEST_CHECK(dst.vb_uint8 == 150);
212 TEST_MSG("Expected 150, got %u", dst.vb_uint8);
213}
214
215static void test_uint8_overflow(void)
216{
217 fr_value_box_t a, b, dst;
218
219 fr_value_box_init(&dst, FR_TYPE_UINT8, NULL, false);
220
221 fr_value_box(&a, (uint8_t) 200, false);
222 fr_value_box(&b, (uint8_t) 200, false);
223
224 /* 200 + 200 = 400, which overflows uint8 (but the intermediate is uint64, then cast to uint8 fails) */
226}
227
228/*
229 * Signed integer tests
230 */
231static void test_int32_add(void)
232{
233 fr_value_box_t a, b, dst;
234
235 fr_value_box_init(&dst, FR_TYPE_INT32, NULL, false);
236
237 fr_value_box(&a, (int32_t) -10, false);
238 fr_value_box(&b, (int32_t) 30, false);
239
241 TEST_CHECK(dst.vb_int32 == 20);
242 TEST_MSG("Expected 20, got %d", dst.vb_int32);
243}
244
245static void test_int32_sub(void)
246{
247 fr_value_box_t a, b, dst;
248
249 fr_value_box_init(&dst, FR_TYPE_INT32, NULL, false);
250
251 fr_value_box(&a, (int32_t) 10, false);
252 fr_value_box(&b, (int32_t) 30, false);
253
255 TEST_CHECK(dst.vb_int32 == -20);
256 TEST_MSG("Expected -20, got %d", dst.vb_int32);
257}
258
259static void test_int32_mul(void)
260{
261 fr_value_box_t a, b, dst;
262
263 fr_value_box_init(&dst, FR_TYPE_INT32, NULL, false);
264
265 fr_value_box(&a, (int32_t) -6, false);
266 fr_value_box(&b, (int32_t) 7, false);
267
269 TEST_CHECK(dst.vb_int32 == -42);
270 TEST_MSG("Expected -42, got %d", dst.vb_int32);
271}
272
273static void test_int32_div(void)
274{
275 fr_value_box_t a, b, dst;
276
277 fr_value_box_init(&dst, FR_TYPE_INT32, NULL, false);
278
279 fr_value_box(&a, (int32_t) -42, false);
280 fr_value_box(&b, (int32_t) 6, false);
281
283 TEST_CHECK(dst.vb_int32 == -7);
284 TEST_MSG("Expected -7, got %d", dst.vb_int32);
285}
286
287static void test_int64_div_zero(void)
288{
289 fr_value_box_t a, b, dst;
290
291 fr_value_box_init(&dst, FR_TYPE_INT64, NULL, false);
292
293 fr_value_box(&a, (int64_t) 42, false);
294 fr_value_box(&b, (int64_t) 0, false);
295
297}
298
299/*
300 * Boolean tests
301 */
302static void test_bool_and(void)
303{
304 fr_value_box_t a, b, dst;
305
306 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
307
308 fr_value_box(&a, (bool) true, false);
309 fr_value_box(&b, (bool) false, false);
310
312 TEST_CHECK(dst.vb_bool == false);
313
314 b.vb_bool = true;
316 TEST_CHECK(dst.vb_bool == true);
317}
318
319static void test_bool_or(void)
320{
321 fr_value_box_t a, b, dst;
322
323 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
324
325 fr_value_box(&a, (bool) false, false);
326 fr_value_box(&b, (bool) false, false);
327
329 TEST_CHECK(dst.vb_bool == false);
330
331 a.vb_bool = true;
333 TEST_CHECK(dst.vb_bool == true);
334}
335
336static void test_bool_xor(void)
337{
338 fr_value_box_t a, b, dst;
339
340 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
341
342 fr_value_box(&a, (bool) true, false);
343 fr_value_box(&b, (bool) true, false);
344
346 TEST_CHECK(dst.vb_bool == false);
347
348 b.vb_bool = false;
350 TEST_CHECK(dst.vb_bool == true);
351}
352
353static void test_bool_add(void)
354{
355 fr_value_box_t a, b, dst;
356
357 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
358
359 /* false + true = true */
360 fr_value_box(&a, (bool) false, false);
361 fr_value_box(&b, (bool) true, false);
363 TEST_CHECK(dst.vb_bool == true);
364
365 /* true + true = overflow */
366 a.vb_bool = true;
367 b.vb_bool = true;
369}
370
371static void test_bool_sub(void)
372{
373 fr_value_box_t a, b, dst;
374
375 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
376
377 /* true - true = false */
378 fr_value_box(&a, (bool) true, false);
379 fr_value_box(&b, (bool) true, false);
381 TEST_CHECK(dst.vb_bool == false);
382
383 /* false - true = underflow */
384 a.vb_bool = false;
385 b.vb_bool = true;
387}
388
389/*
390 * Float64 tests
391 */
392static void test_float64_add(void)
393{
394 fr_value_box_t a, b, dst;
395
396 fr_value_box_init(&dst, FR_TYPE_FLOAT64, NULL, false);
397
398 fr_value_box(&a, (double) 1.5, false);
399 fr_value_box(&b, (double) 2.5, false);
400
402 TEST_CHECK(dst.vb_float64 == 4.0);
403 TEST_MSG("Expected 4.0, got %f", dst.vb_float64);
404}
405
406static void test_float64_sub(void)
407{
408 fr_value_box_t a, b, dst;
409
410 fr_value_box_init(&dst, FR_TYPE_FLOAT64, NULL, false);
411
412 fr_value_box(&a, (double) 10.0, false);
413 fr_value_box(&b, (double) 3.5, false);
414
416 TEST_CHECK(dst.vb_float64 == 6.5);
417 TEST_MSG("Expected 6.5, got %f", dst.vb_float64);
418}
419
420static void test_float64_mul(void)
421{
422 fr_value_box_t a, b, dst;
423
424 fr_value_box_init(&dst, FR_TYPE_FLOAT64, NULL, false);
425
426 fr_value_box(&a, (double) 3.0, false);
427 fr_value_box(&b, (double) 7.0, false);
428
430 TEST_CHECK(dst.vb_float64 == 21.0);
431 TEST_MSG("Expected 21.0, got %f", dst.vb_float64);
432}
433
434static void test_float64_div(void)
435{
436 fr_value_box_t a, b, dst;
437
438 fr_value_box_init(&dst, FR_TYPE_FLOAT64, NULL, false);
439
440 fr_value_box(&a, (double) 22.0, false);
441 fr_value_box(&b, (double) 7.0, false);
442
444 TEST_CHECK((dst.vb_float64 > 3.14) && (dst.vb_float64 < 3.15));
445 TEST_MSG("Expected ~3.14, got %f", dst.vb_float64);
446}
447
448static void test_float64_div_zero(void)
449{
450 fr_value_box_t a, b, dst;
451
452 fr_value_box_init(&dst, FR_TYPE_FLOAT64, NULL, false);
453
454 fr_value_box(&a, (double) 1.0, false);
455 fr_value_box(&b, (double) 0.0, false);
456
458}
459
460static void test_float64_mod(void)
461{
462 fr_value_box_t a, b, dst;
463
464 fr_value_box_init(&dst, FR_TYPE_FLOAT64, NULL, false);
465
466 fr_value_box(&a, (double) 10.5, false);
467 fr_value_box(&b, (double) 3.0, false);
468
470 TEST_CHECK((dst.vb_float64 > 1.49) && (dst.vb_float64 < 1.51));
471 TEST_MSG("Expected ~1.5, got %f", dst.vb_float64);
472}
473
474/*
475 * Float32 tests
476 */
477static void test_float32_add(void)
478{
479 fr_value_box_t a, b, dst;
480
481 fr_value_box_init(&dst, FR_TYPE_FLOAT32, NULL, false);
482
483 fr_value_box(&a, (float) 1.5f, false);
484 fr_value_box(&b, (float) 2.5f, false);
485
487 TEST_CHECK(dst.vb_float32 == 4.0f);
488 TEST_MSG("Expected 4.0, got %f", (double)dst.vb_float32);
489}
490
491static void test_float32_div_zero(void)
492{
493 fr_value_box_t a, b, dst;
494
495 fr_value_box_init(&dst, FR_TYPE_FLOAT32, NULL, false);
496
497 fr_value_box(&a, (float) 1.0f, false);
498 fr_value_box(&b, (float) 0.0f, false);
499
501}
502
503/*
504 * String tests
505 */
506static void test_string_add(void)
507{
508 fr_value_box_t a, b, dst;
509
510 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
511 fr_value_box_init(&b, FR_TYPE_STRING, NULL, false);
512 fr_value_box_init(&dst, FR_TYPE_STRING, NULL, false);
513
514 fr_value_box_strdup(autofree, &a, NULL, "hello ", false);
515 fr_value_box_strdup(autofree, &b, NULL, "world", false);
516
518 TEST_CHECK(strcmp(dst.vb_strvalue, "hello world") == 0);
519 TEST_MSG("Expected 'hello world', got '%s'", dst.vb_strvalue);
520
523 fr_value_box_clear(&dst);
524}
525
526static void test_string_sub(void)
527{
528 fr_value_box_t a, b, dst;
529
530 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
531 fr_value_box_init(&b, FR_TYPE_STRING, NULL, false);
532 fr_value_box_init(&dst, FR_TYPE_STRING, NULL, false);
533
534 fr_value_box_strdup(autofree, &a, NULL, "hello world", false);
535 fr_value_box_strdup(autofree, &b, NULL, "world", false);
536
538 TEST_CHECK(strcmp(dst.vb_strvalue, "hello ") == 0);
539 TEST_MSG("Expected 'hello ', got '%s'", dst.vb_strvalue);
540
543 fr_value_box_clear(&dst);
544}
545
547{
548 fr_value_box_t a, b, dst;
549
550 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
551 fr_value_box_init(&b, FR_TYPE_STRING, NULL, false);
552 fr_value_box_init(&dst, FR_TYPE_STRING, NULL, false);
553
554 fr_value_box_strdup(autofree, &a, NULL, "hello world", false);
555 fr_value_box_strdup(autofree, &b, NULL, "hello", false);
556
557 /* "hello" is not a suffix of "hello world" */
559
562}
563
564static void test_string_xor_prepend(void)
565{
566 fr_value_box_t a, b, dst;
567
568 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
569 fr_value_box_init(&b, FR_TYPE_STRING, NULL, false);
570 fr_value_box_init(&dst, FR_TYPE_STRING, NULL, false);
571
572 fr_value_box_strdup(autofree, &a, NULL, "world", false);
573 fr_value_box_strdup(autofree, &b, NULL, "hello ", false);
574
575 /* XOR on strings is prepend: b is prepended to a */
577 TEST_CHECK(strcmp(dst.vb_strvalue, "hello world") == 0);
578 TEST_MSG("Expected 'hello world', got '%s'", dst.vb_strvalue);
579
582 fr_value_box_clear(&dst);
583}
584
585static void test_string_rshift(void)
586{
587 fr_value_box_t a, b, dst;
588
589 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
590 fr_value_box_init(&dst, FR_TYPE_STRING, NULL, false);
591
592 fr_value_box_strdup(autofree, &a, NULL, "hello world", false);
593 fr_value_box(&b, (uint32_t) 6, false); /* remove 6 chars from the right */
594
596 TEST_CHECK(strcmp(dst.vb_strvalue, "hello") == 0);
597 TEST_MSG("Expected 'hello', got '%s'", dst.vb_strvalue);
598
600 fr_value_box_clear(&dst);
601}
602
603static void test_string_lshift(void)
604{
605 fr_value_box_t a, b, dst;
606
607 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
608 fr_value_box_init(&dst, FR_TYPE_STRING, NULL, false);
609
610 fr_value_box_strdup(autofree, &a, NULL, "hello world", false);
611 fr_value_box(&b, (uint32_t) 6, false); /* remove 6 chars from the left */
612
614 TEST_CHECK(strcmp(dst.vb_strvalue, "world") == 0);
615 TEST_MSG("Expected 'world', got '%s'", dst.vb_strvalue);
616
618 fr_value_box_clear(&dst);
619}
620
621/*
622 * Octets tests
623 */
624static void test_octets_add(void)
625{
626 fr_value_box_t a, b, dst;
627
628 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
629 fr_value_box_init(&b, FR_TYPE_OCTETS, NULL, false);
630 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
631
632 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\x01\x02", 2, false);
633 fr_value_box_memdup(autofree, &b, NULL, (uint8_t const *)"\x03\x04", 2, false);
634
636 TEST_CHECK(dst.vb_length == 4);
637 TEST_CHECK(memcmp(dst.vb_octets, "\x01\x02\x03\x04", 4) == 0);
638
641 fr_value_box_clear(&dst);
642}
643
644static void test_octets_sub(void)
645{
646 fr_value_box_t a, b, dst;
647
648 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
649 fr_value_box_init(&b, FR_TYPE_OCTETS, NULL, false);
650 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
651
652 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\x01\x02\x03\x04", 4, false);
653 fr_value_box_memdup(autofree, &b, NULL, (uint8_t const *)"\x03\x04", 2, false);
654
656 TEST_CHECK(dst.vb_length == 2);
657 TEST_CHECK(memcmp(dst.vb_octets, "\x01\x02", 2) == 0);
658
661 fr_value_box_clear(&dst);
662}
663
664static void test_octets_and(void)
665{
666 fr_value_box_t a, b, dst;
667
668 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
669 fr_value_box_init(&b, FR_TYPE_OCTETS, NULL, false);
670 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
671
672 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\xff\x0f", 2, false);
673 fr_value_box_memdup(autofree, &b, NULL, (uint8_t const *)"\x0f\xff", 2, false);
674
676 TEST_CHECK(dst.vb_length == 2);
677 TEST_CHECK(memcmp(dst.vb_octets, "\x0f\x0f", 2) == 0);
678
681 fr_value_box_clear(&dst);
682}
683
684static void test_octets_or(void)
685{
686 fr_value_box_t a, b, dst;
687
688 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
689 fr_value_box_init(&b, FR_TYPE_OCTETS, NULL, false);
690 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
691
692 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\xf0\x0f", 2, false);
693 fr_value_box_memdup(autofree, &b, NULL, (uint8_t const *)"\x0f\xf0", 2, false);
694
696 TEST_CHECK(dst.vb_length == 2);
697 TEST_CHECK(memcmp(dst.vb_octets, "\xff\xff", 2) == 0);
698
701 fr_value_box_clear(&dst);
702}
703
704static void test_octets_xor(void)
705{
706 fr_value_box_t a, b, dst;
707
708 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
709 fr_value_box_init(&b, FR_TYPE_OCTETS, NULL, false);
710 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
711
712 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\xff\x00", 2, false);
713 fr_value_box_memdup(autofree, &b, NULL, (uint8_t const *)"\x0f\x0f", 2, false);
714
716 TEST_CHECK(dst.vb_length == 2);
717 TEST_CHECK(memcmp(dst.vb_octets, "\xf0\x0f", 2) == 0);
718
721 fr_value_box_clear(&dst);
722}
723
725{
726 fr_value_box_t a, b, dst;
727
728 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
729 fr_value_box_init(&b, FR_TYPE_OCTETS, NULL, false);
730 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
731
732 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\xff\x00\x01", 3, false);
733 fr_value_box_memdup(autofree, &b, NULL, (uint8_t const *)"\x0f\x0f", 2, false);
734
735 /* AND/OR/XOR require same length */
739
742}
743
744static void test_octets_rshift(void)
745{
746 fr_value_box_t a, b, dst;
747
748 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
749 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
750
751 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\x01\x02\x03\x04", 4, false);
752 fr_value_box(&b, (uint32_t) 2, false); /* remove 2 bytes from the right */
753
755 TEST_CHECK(dst.vb_length == 2);
756 TEST_CHECK(memcmp(dst.vb_octets, "\x01\x02", 2) == 0);
757
759 fr_value_box_clear(&dst);
760}
761
762static void test_octets_lshift(void)
763{
764 fr_value_box_t a, b, dst;
765
766 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
767 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
768
769 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\x01\x02\x03\x04", 4, false);
770 fr_value_box(&b, (uint32_t) 2, false); /* remove 2 bytes from the left */
771
773 TEST_CHECK(dst.vb_length == 2);
774 TEST_CHECK(memcmp(dst.vb_octets, "\x03\x04", 2) == 0);
775
777 fr_value_box_clear(&dst);
778}
779
780/*
781 * Comparison tests
782 */
783static void test_cmp_eq(void)
784{
785 fr_value_box_t a, b, dst;
786
787 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
788
789 fr_value_box(&a, (uint32_t) 42, false);
790 fr_value_box(&b, (uint32_t) 42, false);
791
792 /*
793 * T_OP_CMP and friends return "1" for "true", "0" for "false", and -1 for error.
794 */
796 TEST_CHECK(dst.vb_bool == true);
797
798 b.vb_uint32 = 43;
800 TEST_CHECK(dst.vb_bool == false);
801}
802
803static void test_cmp_ne(void)
804{
805 fr_value_box_t a, b, dst;
806
807 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
808
809 fr_value_box(&a, (uint32_t) 42, false);
810 fr_value_box(&b, (uint32_t) 43, false);
811
813 TEST_CHECK(dst.vb_bool == true);
814
815 b.vb_uint32 = 42;
817 TEST_CHECK(dst.vb_bool == false);
818}
819
820static void test_cmp_lt(void)
821{
822 fr_value_box_t a, b, dst;
823
824 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
825
826 fr_value_box(&a, (uint32_t) 10, false);
827 fr_value_box(&b, (uint32_t) 20, false);
828
830 TEST_CHECK(dst.vb_bool == true);
831
832 a.vb_uint32 = 20;
834 TEST_CHECK(dst.vb_bool == false);
835}
836
837static void test_cmp_gt(void)
838{
839 fr_value_box_t a, b, dst;
840
841 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
842
843 fr_value_box(&a, (uint32_t) 20, false);
844 fr_value_box(&b, (uint32_t) 10, false);
845
847 TEST_CHECK(dst.vb_bool == true);
848
849 a.vb_uint32 = 10;
851 TEST_CHECK(dst.vb_bool == false);
852}
853
854static void test_cmp_le(void)
855{
856 fr_value_box_t a, b, dst;
857
858 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
859
860 fr_value_box(&a, (uint32_t) 10, false);
861 fr_value_box(&b, (uint32_t) 10, false);
862
864 TEST_CHECK(dst.vb_bool == true);
865
866 a.vb_uint32 = 11;
868 TEST_CHECK(dst.vb_bool == false);
869}
870
871static void test_cmp_ge(void)
872{
873 fr_value_box_t a, b, dst;
874
875 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
876
877 fr_value_box(&a, (uint32_t) 10, false);
878 fr_value_box(&b, (uint32_t) 10, false);
879
881 TEST_CHECK(dst.vb_bool == true);
882
883 a.vb_uint32 = 9;
885 TEST_CHECK(dst.vb_bool == false);
886}
887
888static void test_cmp_eq_type(void)
889{
890 fr_value_box_t a, b, dst;
891
892 /* Same type, same value */
893 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
894
895 fr_value_box(&a, (uint32_t) 42, false);
896 fr_value_box(&b, (uint32_t) 42, false);
897
899 TEST_CHECK(dst.vb_bool == true);
900
901 /* Different types -> always false */
902 fr_value_box(&b, (uint64_t) 42, false);
903
905 TEST_CHECK(dst.vb_bool == false);
906}
907
908/*
909 * Unary operation tests
910 */
911static void test_unary_increment(void)
912{
913 fr_value_box_t src, dst;
914
915 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
916
917 fr_value_box(&src, (uint32_t) 41, false);
918
920 TEST_CHECK(dst.vb_uint32 == 42);
921 TEST_MSG("Expected 42, got %u", dst.vb_uint32);
922}
923
924static void test_unary_complement(void)
925{
926 fr_value_box_t src, dst;
927
928 fr_value_box_init(&dst, FR_TYPE_UINT8, NULL, false);
929
930 fr_value_box(&src, (uint8_t) 0x0f, false);
931
933 TEST_CHECK(dst.vb_uint8 == 0xf0);
934 TEST_MSG("Expected 0xf0, got 0x%02x", dst.vb_uint8);
935}
936
937static void test_unary_negate(void)
938{
939 fr_value_box_t src, dst;
940
941 fr_value_box_init(&dst, FR_TYPE_INT32, NULL, false);
942
943 fr_value_box(&src, (int32_t) 42, false);
944
946 TEST_CHECK(dst.vb_int32 == -42);
947 TEST_MSG("Expected -42, got %d", dst.vb_int32);
948}
949
950static void test_unary_not(void)
951{
952 fr_value_box_t src, dst;
953
954 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
955
956 fr_value_box(&src, (uint32_t) 42, false);
957
959 TEST_CHECK(dst.vb_bool == false);
960
961 src.vb_uint32 = 0;
963 TEST_CHECK(dst.vb_bool == true);
964}
965
966/*
967 * Assignment operation tests
968 */
969static void test_assign_add(void)
970{
971 fr_value_box_t dst, src;
972
973
974 fr_value_box(&dst, (uint32_t) 10, false);
975 fr_value_box(&src, (uint32_t) 5, false);
976
978 TEST_CHECK(dst.vb_uint32 == 15);
979 TEST_MSG("Expected 15, got %u", dst.vb_uint32);
980}
981
982static void test_assign_sub(void)
983{
984 fr_value_box_t dst, src;
985
986
987 fr_value_box(&dst, (uint32_t) 10, false);
988 fr_value_box(&src, (uint32_t) 3, false);
989
991 TEST_CHECK(dst.vb_uint32 == 7);
992 TEST_MSG("Expected 7, got %u", dst.vb_uint32);
993}
994
995static void test_assign_set(void)
996{
997 fr_value_box_t dst, src;
998
999
1000 fr_value_box(&dst, (uint32_t) 10, false);
1001 fr_value_box(&src, (uint32_t) 99, false);
1002
1004 TEST_CHECK(dst.vb_uint32 == 99);
1005 TEST_MSG("Expected 99, got %u", dst.vb_uint32);
1006}
1007
1008static void test_assign_self(void)
1009{
1010 fr_value_box_t dst;
1011
1012 fr_value_box(&dst, (uint32_t) 42, false);
1013
1014 /* Assigning to self should be a no-op */
1016 TEST_CHECK(dst.vb_uint32 == 42);
1017}
1018
1019/*
1020 * Type coercion tests - mixed type operations
1021 */
1023{
1024 fr_value_box_t a, b, dst;
1025
1026 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
1027
1028 fr_value_box(&a, (uint8_t) 10, false);
1029 fr_value_box(&b, (uint32_t) 20, false);
1030
1032 TEST_CHECK(dst.vb_uint32 == 30);
1033 TEST_MSG("Expected 30, got %u", dst.vb_uint32);
1034}
1035
1036static void test_auto_type_hint(void)
1037{
1038 fr_value_box_t a, b, dst;
1039
1041
1042 fr_value_box(&a, (uint32_t) 10, false);
1043 fr_value_box(&b, (uint32_t) 20, false);
1044
1045 /* Let the function figure out the output type */
1047 TEST_CHECK(dst.type == FR_TYPE_UINT64); /* uint32 + uint32 upcasts to uint64 */
1048 TEST_CHECK(dst.vb_uint64 == 30);
1049 TEST_MSG("Expected 30, got %" PRIu64, dst.vb_uint64);
1050}
1051
1052/*
1053 * Comparison with different types
1054 */
1056{
1057 fr_value_box_t a, b, dst;
1058
1059 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
1060
1061 fr_value_box(&a, (uint8_t) 10, false);
1062 fr_value_box(&b, (uint32_t) 10, false);
1063
1065 TEST_CHECK(dst.vb_bool == true);
1066
1067 a.vb_uint8 = 10;
1068 b.vb_uint32 = 20;
1070 TEST_CHECK(dst.vb_bool == true);
1071}
1072
1073/*
1074 * uint64 edge cases
1075 */
1076static void test_uint64_overflow(void)
1077{
1078 fr_value_box_t a, b, dst;
1079
1080 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1081
1082 fr_value_box(&a, (uint64_t) UINT64_MAX, false);
1083 fr_value_box(&b, (uint64_t) 1, false);
1084
1086}
1087
1088static void test_uint64_underflow(void)
1089{
1090 fr_value_box_t a, b, dst;
1091
1092 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1093
1094 fr_value_box(&a, (uint64_t) 0, false);
1095 fr_value_box(&b, (uint64_t) 1, false);
1096
1098}
1099
1101{
1102 fr_value_box_t a, b, dst;
1103
1104 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1105
1106 fr_value_box(&a, (uint64_t) UINT64_MAX, false);
1107 fr_value_box(&b, (uint64_t) 2, false);
1108
1110}
1111
1112/*
1113 * int64 edge cases
1114 */
1115static void test_int64_overflow(void)
1116{
1117 fr_value_box_t a, b, dst;
1118
1119 fr_value_box_init(&dst, FR_TYPE_INT64, NULL, false);
1120
1121 fr_value_box(&a, (int64_t) INT64_MAX, false);
1122 fr_value_box(&b, (int64_t) 1, false);
1123
1125}
1126
1127static void test_int64_underflow(void)
1128{
1129 fr_value_box_t a, b, dst;
1130
1131 fr_value_box_init(&dst, FR_TYPE_INT64, NULL, false);
1132
1133 fr_value_box(&a, (int64_t) INT64_MIN, false);
1134 fr_value_box(&b, (int64_t) 1, false);
1135
1137}
1138
1139/*
1140 * uint16 tests
1141 */
1142static void test_uint16_add(void)
1143{
1144 fr_value_box_t a, b, dst;
1145
1146 fr_value_box_init(&dst, FR_TYPE_UINT16, NULL, false);
1147
1148 fr_value_box(&a, (uint16_t) 1000, false);
1149 fr_value_box(&b, (uint16_t) 2000, false);
1150
1152 TEST_CHECK(dst.vb_uint16 == 3000);
1153 TEST_MSG("Expected 3000, got %u", dst.vb_uint16);
1154}
1155
1156static void test_uint16_overflow(void)
1157{
1158 fr_value_box_t a, b, dst;
1159
1160 fr_value_box_init(&dst, FR_TYPE_UINT16, NULL, false);
1161
1162 fr_value_box(&a, (uint16_t) 60000, false);
1163 fr_value_box(&b, (uint16_t) 60000, false);
1164
1165 /* 60000 + 60000 = 120000, which overflows uint16 */
1167}
1168
1169/*
1170 * uint64 bitwise and shift tests
1171 */
1172static void test_uint64_and(void)
1173{
1174 fr_value_box_t a, b, dst;
1175
1176 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1177
1178 fr_value_box(&a, (uint64_t) 0xff00ff00ff00ff00ULL, false);
1179 fr_value_box(&b, (uint64_t) 0x0f0f0f0f0f0f0f0fULL, false);
1180
1182 TEST_CHECK(dst.vb_uint64 == 0x0f000f000f000f00ULL);
1183 TEST_MSG("Expected 0x0f000f000f000f00, got 0x%" PRIx64, dst.vb_uint64);
1184}
1185
1186static void test_uint64_or(void)
1187{
1188 fr_value_box_t a, b, dst;
1189
1190 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1191
1192 fr_value_box(&a, (uint64_t) 0xf0f0f0f000000000ULL, false);
1193 fr_value_box(&b, (uint64_t) 0x000000000f0f0f0fULL, false);
1194
1196 TEST_CHECK(dst.vb_uint64 == 0xf0f0f0f00f0f0f0fULL);
1197 TEST_MSG("Expected 0xf0f0f0f00f0f0f0f, got 0x%" PRIx64, dst.vb_uint64);
1198}
1199
1200static void test_uint64_xor(void)
1201{
1202 fr_value_box_t a, b, dst;
1203
1204 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1205
1206 fr_value_box(&a, (uint64_t) 0xffffffffffffffffULL, false);
1207 fr_value_box(&b, (uint64_t) 0x0f0f0f0f0f0f0f0fULL, false);
1208
1210 TEST_CHECK(dst.vb_uint64 == 0xf0f0f0f0f0f0f0f0ULL);
1211 TEST_MSG("Expected 0xf0f0f0f0f0f0f0f0, got 0x%" PRIx64, dst.vb_uint64);
1212}
1213
1214static void test_uint64_shift(void)
1215{
1216 fr_value_box_t a, b, dst;
1217
1218 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1219
1220 fr_value_box(&a, (uint64_t) 0x100, false);
1221 fr_value_box(&b, (uint32_t) 8, false);
1222
1223 /* left shift */
1225 TEST_CHECK(dst.vb_uint64 == 0x10000);
1226 TEST_MSG("Expected 0x10000, got 0x%" PRIx64, dst.vb_uint64);
1227
1228 /* right shift */
1230 TEST_CHECK(dst.vb_uint64 == 0x01);
1231 TEST_MSG("Expected 0x01, got 0x%" PRIx64, dst.vb_uint64);
1232}
1233
1235{
1236 fr_value_box_t a, b, dst;
1237
1238 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1239
1240 fr_value_box(&a, (uint64_t) 1, false);
1241 fr_value_box(&b, (uint32_t) 64, false); /* shift by >= bitsize is error */
1242
1245}
1246
1247static void test_uint64_mod(void)
1248{
1249 fr_value_box_t a, b, dst;
1250
1251 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1252
1253 fr_value_box(&a, (uint64_t) 100, false);
1254 fr_value_box(&b, (uint64_t) 7, false);
1255
1257 TEST_CHECK(dst.vb_uint64 == 2);
1258 TEST_MSG("Expected 2, got %" PRIu64, dst.vb_uint64);
1259}
1260
1261static void test_uint64_div(void)
1262{
1263 fr_value_box_t a, b, dst;
1264
1265 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1266
1267 fr_value_box(&a, (uint64_t) 100, false);
1268 fr_value_box(&b, (uint64_t) 7, false);
1269
1271 TEST_CHECK(dst.vb_uint64 == 14);
1272 TEST_MSG("Expected 14, got %" PRIu64, dst.vb_uint64);
1273}
1274
1275static void test_uint64_div_zero(void)
1276{
1277 fr_value_box_t a, b, dst;
1278
1279 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1280
1281 fr_value_box(&a, (uint64_t) 100, false);
1282 fr_value_box(&b, (uint64_t) 0, false);
1283
1286}
1287
1288/*
1289 * int8 tests
1290 */
1291static void test_int8_add(void)
1292{
1293 fr_value_box_t a, b, dst;
1294
1295 fr_value_box_init(&dst, FR_TYPE_INT8, NULL, false);
1296
1297 fr_value_box(&a, (int8_t) -50, false);
1298 fr_value_box(&b, (int8_t) 100, false);
1299
1301 TEST_CHECK(dst.vb_int8 == 50);
1302 TEST_MSG("Expected 50, got %d", dst.vb_int8);
1303}
1304
1305static void test_int8_sub(void)
1306{
1307 fr_value_box_t a, b, dst;
1308
1309 fr_value_box_init(&dst, FR_TYPE_INT8, NULL, false);
1310
1311 fr_value_box(&a, (int8_t) 50, false);
1312 fr_value_box(&b, (int8_t) 100, false);
1313
1315 TEST_CHECK(dst.vb_int8 == -50);
1316 TEST_MSG("Expected -50, got %d", dst.vb_int8);
1317}
1318
1319/*
1320 * int16 tests
1321 */
1322static void test_int16_add(void)
1323{
1324 fr_value_box_t a, b, dst;
1325
1326 fr_value_box_init(&dst, FR_TYPE_INT16, NULL, false);
1327
1328 fr_value_box(&a, (int16_t) -1000, false);
1329 fr_value_box(&b, (int16_t) 2000, false);
1330
1332 TEST_CHECK(dst.vb_int16 == 1000);
1333 TEST_MSG("Expected 1000, got %d", dst.vb_int16);
1334}
1335
1336/*
1337 * int32 additional ops
1338 */
1339static void test_int32_mod(void)
1340{
1341 fr_value_box_t a, b, dst;
1342
1343 fr_value_box_init(&dst, FR_TYPE_INT32, NULL, false);
1344
1345 fr_value_box(&a, (int32_t) -17, false);
1346 fr_value_box(&b, (int32_t) 5, false);
1347
1349 TEST_CHECK(dst.vb_int32 == -2);
1350 TEST_MSG("Expected -2, got %d", dst.vb_int32);
1351}
1352
1353/*
1354 * int64 bitwise and shift
1355 */
1356static void test_int64_and(void)
1357{
1358 fr_value_box_t a, b, dst;
1359
1360 fr_value_box_init(&dst, FR_TYPE_INT64, NULL, false);
1361
1362 fr_value_box(&a, (int64_t) 0x0fff, false);
1363 fr_value_box(&b, (int64_t) 0x00ff, false);
1364
1366 TEST_CHECK(dst.vb_int64 == 0x00ff);
1367 TEST_MSG("Expected 0x00ff, got 0x%" PRIx64, dst.vb_int64);
1368}
1369
1370static void test_int64_or(void)
1371{
1372 fr_value_box_t a, b, dst;
1373
1374 fr_value_box_init(&dst, FR_TYPE_INT64, NULL, false);
1375
1376 fr_value_box(&a, (int64_t) 0xf000, false);
1377 fr_value_box(&b, (int64_t) 0x000f, false);
1378
1380 TEST_CHECK(dst.vb_int64 == 0xf00f);
1381 TEST_MSG("Expected 0xf00f, got 0x%" PRIx64, dst.vb_int64);
1382}
1383
1384static void test_int64_xor(void)
1385{
1386 fr_value_box_t a, b, dst;
1387
1388 fr_value_box_init(&dst, FR_TYPE_INT64, NULL, false);
1389
1390 fr_value_box(&a, (int64_t) 0xffff, false);
1391 fr_value_box(&b, (int64_t) 0x0f0f, false);
1392
1394 TEST_CHECK(dst.vb_int64 == 0xf0f0);
1395 TEST_MSG("Expected 0xf0f0, got 0x%" PRIx64, dst.vb_int64);
1396}
1397
1398static void test_int64_shift(void)
1399{
1400 fr_value_box_t a, b, dst;
1401
1402 fr_value_box_init(&dst, FR_TYPE_INT64, NULL, false);
1403
1404 fr_value_box(&a, (int64_t) 0x100, false);
1405 fr_value_box(&b, (uint32_t) 4, false);
1406
1407 /* left shift */
1409 TEST_CHECK(dst.vb_int64 == 0x1000);
1410 TEST_MSG("Expected 0x1000, got 0x%" PRIx64, dst.vb_int64);
1411
1412 /* right shift */
1414 TEST_CHECK(dst.vb_int64 == 0x10);
1415 TEST_MSG("Expected 0x10, got 0x%" PRIx64, dst.vb_int64);
1416}
1417
1419{
1420 fr_value_box_t a, b, dst;
1421
1422 fr_value_box_init(&dst, FR_TYPE_INT64, NULL, false);
1423
1424 fr_value_box(&a, (int64_t) 1, false);
1425 fr_value_box(&b, (uint32_t) 64, false);
1426
1429}
1430
1431static void test_int64_mod(void)
1432{
1433 fr_value_box_t a, b, dst;
1434
1435 fr_value_box_init(&dst, FR_TYPE_INT64, NULL, false);
1436
1437 fr_value_box(&a, (int64_t) 100, false);
1438 fr_value_box(&b, (int64_t) 7, false);
1439
1441 TEST_CHECK(dst.vb_int64 == 2);
1442 TEST_MSG("Expected 2, got %" PRId64, dst.vb_int64);
1443}
1444
1445/*
1446 * Float32 additional ops
1447 */
1448static void test_float32_sub(void)
1449{
1450 fr_value_box_t a, b, dst;
1451
1452 fr_value_box_init(&dst, FR_TYPE_FLOAT32, NULL, false);
1453
1454 fr_value_box(&a, (float) 10.0f, false);
1455 fr_value_box(&b, (float) 3.5f, false);
1456
1458 TEST_CHECK(dst.vb_float32 == 6.5f);
1459 TEST_MSG("Expected 6.5, got %f", (double)dst.vb_float32);
1460}
1461
1462static void test_float32_mul(void)
1463{
1464 fr_value_box_t a, b, dst;
1465
1466 fr_value_box_init(&dst, FR_TYPE_FLOAT32, NULL, false);
1467
1468 fr_value_box(&a, (float) 3.0f, false);
1469 fr_value_box(&b, (float) 7.0f, false);
1470
1472 TEST_CHECK(dst.vb_float32 == 21.0f);
1473 TEST_MSG("Expected 21.0, got %f", (double)dst.vb_float32);
1474}
1475
1476static void test_float32_div(void)
1477{
1478 fr_value_box_t a, b, dst;
1479
1480 fr_value_box_init(&dst, FR_TYPE_FLOAT32, NULL, false);
1481
1482 fr_value_box(&a, (float) 21.0f, false);
1483 fr_value_box(&b, (float) 7.0f, false);
1484
1486 TEST_CHECK(dst.vb_float32 == 3.0f);
1487 TEST_MSG("Expected 3.0, got %f", (double)dst.vb_float32);
1488}
1489
1490static void test_float32_mod(void)
1491{
1492 fr_value_box_t a, b, dst;
1493
1494 fr_value_box_init(&dst, FR_TYPE_FLOAT32, NULL, false);
1495
1496 fr_value_box(&a, (float) 10.5f, false);
1497 fr_value_box(&b, (float) 3.0f, false);
1498
1500 TEST_CHECK((dst.vb_float32 > 1.49f) && (dst.vb_float32 < 1.51f));
1501 TEST_MSG("Expected ~1.5, got %f", (double)dst.vb_float32);
1502}
1503
1504static void test_float32_mod_zero(void)
1505{
1506 fr_value_box_t a, b, dst;
1507
1508 fr_value_box_init(&dst, FR_TYPE_FLOAT32, NULL, false);
1509
1510 fr_value_box(&a, (float) 10.0f, false);
1511 fr_value_box(&b, (float) 0.0f, false);
1512
1514}
1515
1516static void test_float64_mod_zero(void)
1517{
1518 fr_value_box_t a, b, dst;
1519
1520 fr_value_box_init(&dst, FR_TYPE_FLOAT64, NULL, false);
1521
1522 fr_value_box(&a, (double) 10.0, false);
1523 fr_value_box(&b, (double) 0.0, false);
1524
1526}
1527
1528/*
1529 * Bool mul (which acts as AND)
1530 */
1531static void test_bool_mul(void)
1532{
1533 fr_value_box_t a, b, dst;
1534
1535 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
1536
1537 fr_value_box(&a, (bool) true, false);
1538 fr_value_box(&b, (bool) true, false);
1539
1541 TEST_CHECK(dst.vb_bool == true);
1542
1543 b.vb_bool = false;
1545 TEST_CHECK(dst.vb_bool == false);
1546}
1547
1548/*
1549 * String edge cases
1550 */
1552{
1553 fr_value_box_t a, b, dst;
1554
1555 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
1556 fr_value_box_init(&b, FR_TYPE_STRING, NULL, false);
1557 fr_value_box_init(&dst, FR_TYPE_STRING, NULL, false);
1558
1559 fr_value_box_strdup(autofree, &a, NULL, "hi", false);
1560 fr_value_box_strdup(autofree, &b, NULL, "hello world", false);
1561
1562 /* suffix to remove is longer than input */
1564
1567}
1568
1570{
1571 fr_value_box_t a, b, dst;
1572
1573 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
1574 fr_value_box_init(&dst, FR_TYPE_STRING, NULL, false);
1575
1576 fr_value_box_strdup(autofree, &a, NULL, "hi", false);
1577 fr_value_box(&b, (uint32_t) 100, false); /* more than string length */
1578
1580
1582}
1583
1585{
1586 fr_value_box_t a, b, dst;
1587
1588 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
1589 fr_value_box_init(&dst, FR_TYPE_STRING, NULL, false);
1590
1591 fr_value_box_strdup(autofree, &a, NULL, "hi", false);
1592 fr_value_box(&b, (uint32_t) 100, false);
1593
1595
1597}
1598
1599static void test_string_add_empty(void)
1600{
1601 fr_value_box_t a, b, dst;
1602
1603 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
1604 fr_value_box_init(&b, FR_TYPE_STRING, NULL, false);
1605 fr_value_box_init(&dst, FR_TYPE_STRING, NULL, false);
1606
1607 fr_value_box_strdup(autofree, &a, NULL, "hello", false);
1608 fr_value_box_strdup(autofree, &b, NULL, "", false);
1609
1611 TEST_CHECK(strcmp(dst.vb_strvalue, "hello") == 0);
1612 TEST_MSG("Expected 'hello', got '%s'", dst.vb_strvalue);
1613
1616 fr_value_box_clear(&dst);
1617}
1618
1619/*
1620 * Octets edge cases
1621 */
1623{
1624 fr_value_box_t a, b, dst;
1625
1626 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
1627 fr_value_box_init(&b, FR_TYPE_OCTETS, NULL, false);
1628 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
1629
1630 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\x01\x02\x03\x04", 4, false);
1631 fr_value_box_memdup(autofree, &b, NULL, (uint8_t const *)"\x01\x02", 2, false);
1632
1633 /* 0x0102 is not a suffix of 0x01020304 */
1635
1638}
1639
1641{
1642 fr_value_box_t a, b, dst;
1643
1644 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
1645 fr_value_box_init(&b, FR_TYPE_OCTETS, NULL, false);
1646 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
1647
1648 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\x01", 1, false);
1649 fr_value_box_memdup(autofree, &b, NULL, (uint8_t const *)"\x01\x02\x03", 3, false);
1650
1652
1655}
1656
1658{
1659 fr_value_box_t a, b, dst;
1660
1661 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
1662 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
1663
1664 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\x01\x02", 2, false);
1665 fr_value_box(&b, (uint32_t) 10, false);
1666
1668
1670}
1671
1673{
1674 fr_value_box_t a, b, dst;
1675
1676 fr_value_box_init(&a, FR_TYPE_OCTETS, NULL, false);
1677 fr_value_box_init(&dst, FR_TYPE_OCTETS, NULL, false);
1678
1679 fr_value_box_memdup(autofree, &a, NULL, (uint8_t const *)"\x01\x02", 2, false);
1680 fr_value_box(&b, (uint32_t) 10, false);
1681
1683
1685}
1686
1687/*
1688 * Assignment compound ops
1689 */
1690static void test_assign_mul(void)
1691{
1692 fr_value_box_t dst, src;
1693
1694
1695 fr_value_box(&dst, (uint32_t) 6, false);
1696 fr_value_box(&src, (uint32_t) 7, false);
1697
1699 TEST_CHECK(dst.vb_uint32 == 42);
1700 TEST_MSG("Expected 42, got %u", dst.vb_uint32);
1701}
1702
1703static void test_assign_div(void)
1704{
1705 fr_value_box_t dst, src;
1706
1707
1708 fr_value_box(&dst, (uint32_t) 42, false);
1709 fr_value_box(&src, (uint32_t) 6, false);
1710
1712 TEST_CHECK(dst.vb_uint32 == 7);
1713 TEST_MSG("Expected 7, got %u", dst.vb_uint32);
1714}
1715
1716static void test_assign_and(void)
1717{
1718 fr_value_box_t dst, src;
1719
1720
1721 fr_value_box(&dst, (uint32_t) 0xff, false);
1722 fr_value_box(&src, (uint32_t) 0x0f, false);
1723
1725 TEST_CHECK(dst.vb_uint32 == 0x0f);
1726 TEST_MSG("Expected 0x0f, got 0x%x", dst.vb_uint32);
1727}
1728
1729static void test_assign_or(void)
1730{
1731 fr_value_box_t dst, src;
1732
1733
1734 fr_value_box(&dst, (uint32_t) 0xf0, false);
1735 fr_value_box(&src, (uint32_t) 0x0f, false);
1736
1738 TEST_CHECK(dst.vb_uint32 == 0xff);
1739 TEST_MSG("Expected 0xff, got 0x%x", dst.vb_uint32);
1740}
1741
1742static void test_assign_xor(void)
1743{
1744 fr_value_box_t dst, src;
1745
1746
1747 fr_value_box(&dst, (uint32_t) 0xff, false);
1748 fr_value_box(&src, (uint32_t) 0x0f, false);
1749
1751 TEST_CHECK(dst.vb_uint32 == 0xf0);
1752 TEST_MSG("Expected 0xf0, got 0x%x", dst.vb_uint32);
1753}
1754
1755static void test_assign_rshift(void)
1756{
1757 fr_value_box_t dst, src;
1758
1759
1760 fr_value_box(&dst, (uint32_t) 0x100, false);
1761 fr_value_box(&src, (uint32_t) 4, false);
1762
1764 TEST_CHECK(dst.vb_uint32 == 0x10);
1765 TEST_MSG("Expected 0x10, got 0x%x", dst.vb_uint32);
1766}
1767
1768static void test_assign_lshift(void)
1769{
1770 fr_value_box_t dst, src;
1771
1772
1773 fr_value_box(&dst, (uint32_t) 0x10, false);
1774 fr_value_box(&src, (uint32_t) 4, false);
1775
1777 TEST_CHECK(dst.vb_uint32 == 0x100);
1778 TEST_MSG("Expected 0x100, got 0x%x", dst.vb_uint32);
1779}
1780
1781/*
1782 * Unary tests on additional types
1783 */
1785{
1786 fr_value_box_t src, dst;
1787
1788 fr_value_box_init(&dst, FR_TYPE_UINT16, NULL, false);
1789
1790 fr_value_box(&src, (uint16_t) 0x00ff, false);
1791
1793 TEST_CHECK(dst.vb_uint16 == 0xff00);
1794 TEST_MSG("Expected 0xff00, got 0x%04x", dst.vb_uint16);
1795}
1796
1798{
1799 fr_value_box_t src, dst;
1800
1801 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
1802
1803 fr_value_box(&src, (uint32_t) 0x0000ffff, false);
1804
1806 TEST_CHECK(dst.vb_uint32 == 0xffff0000);
1807 TEST_MSG("Expected 0xffff0000, got 0x%08x", dst.vb_uint32);
1808}
1809
1811{
1812 fr_value_box_t src, dst;
1813
1814 fr_value_box_init(&dst, FR_TYPE_UINT64, NULL, false);
1815
1816 fr_value_box(&src, (uint64_t) 0, false);
1817
1819 TEST_CHECK(dst.vb_uint64 == UINT64_MAX);
1820 TEST_MSG("Expected UINT64_MAX, got 0x%" PRIx64, dst.vb_uint64);
1821}
1822
1824{
1825 fr_value_box_t src, dst;
1826
1827 fr_value_box_init(&dst, FR_TYPE_INT32, NULL, false);
1828
1829 fr_value_box(&src, (int32_t) 0, false);
1830
1832 TEST_CHECK(dst.vb_int32 == -1);
1833 TEST_MSG("Expected -1, got %d", dst.vb_int32);
1834}
1835
1837{
1838 fr_value_box_t src, dst;
1839
1840 fr_value_box_init(&dst, FR_TYPE_FLOAT64, NULL, false);
1841
1842 fr_value_box(&src, (double) 3.14, false);
1843
1844 TEST_CHECK(fr_value_calc_unary_op(autofree, &dst, T_SUB, &src) == 0);
1845 TEST_CHECK((dst.vb_float64 > -3.15) && (dst.vb_float64 < -3.13));
1846 TEST_MSG("Expected -3.14, got %f", dst.vb_float64);
1847}
1848
1850{
1851 fr_value_box_t src, dst;
1852
1853 fr_value_box_init(&dst, FR_TYPE_UINT8, NULL, false);
1854
1855 fr_value_box(&src, (uint8_t) 254, false);
1856
1858 TEST_CHECK(dst.vb_uint8 == 255);
1859 TEST_MSG("Expected 255, got %u", dst.vb_uint8);
1860}
1861
1863{
1864 fr_value_box_t src, dst;
1865
1866 fr_value_box_init(&dst, FR_TYPE_UINT8, NULL, false);
1867
1868 fr_value_box(&src, (uint8_t) 255, false);
1869
1870 /* 255 + 1 overflows uint8 */
1872}
1873
1874static void test_unary_not_bool(void)
1875{
1876 fr_value_box_t src, dst;
1877
1878 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
1879
1880 fr_value_box(&src, (bool) true, false);
1881
1882 TEST_CHECK(fr_value_calc_unary_op(autofree, &dst, T_NOT, &src) == 0);
1883 TEST_CHECK(dst.vb_bool == false);
1884
1885 src.vb_bool = false;
1886 TEST_CHECK(fr_value_calc_unary_op(autofree, &dst, T_NOT, &src) == 0);
1887 TEST_CHECK(dst.vb_bool == true);
1888}
1889
1891{
1892 fr_value_box_t src, dst;
1893
1894 fr_value_box_init(&dst, FR_TYPE_INT64, NULL, false);
1895
1896 fr_value_box(&src, (int64_t) -1, false);
1897
1899 TEST_CHECK(dst.vb_int64 == 0);
1900 TEST_MSG("Expected 0, got %" PRId64, dst.vb_int64);
1901}
1902
1904{
1905 fr_value_box_t src, dst;
1906
1907 fr_value_box_init(&dst, FR_TYPE_FLOAT64, NULL, false);
1908
1909 fr_value_box(&src, (double) 2.5, false);
1910
1912 TEST_CHECK(dst.vb_float64 == 3.5);
1913 TEST_MSG("Expected 3.5, got %f", dst.vb_float64);
1914}
1915
1916/*
1917 * Auto type hint for subtract
1918 */
1920{
1921 fr_value_box_t a, b, dst;
1922
1924
1925 fr_value_box(&a, (uint32_t) 30, false);
1926 fr_value_box(&b, (uint32_t) 10, false);
1927
1929 TEST_CHECK(dst.type == FR_TYPE_UINT64);
1930 TEST_CHECK(dst.vb_uint64 == 20);
1931 TEST_MSG("Expected 20, got %" PRIu64, dst.vb_uint64);
1932}
1933
1934/*
1935 * Auto type hint for lshift
1936 */
1938{
1939 fr_value_box_t a, b, dst;
1940
1942
1943 fr_value_box(&a, (uint32_t) 1, false);
1944 fr_value_box(&b, (uint32_t) 8, false);
1945
1946 /* auto type hint for lshift on unsigned should become uint64 */
1948 TEST_CHECK(dst.type == FR_TYPE_UINT64);
1949 TEST_CHECK(dst.vb_uint64 == 256);
1950 TEST_MSG("Expected 256, got %" PRIu64, dst.vb_uint64);
1951}
1952
1953/*
1954 * Mixed signed and unsigned
1955 */
1957{
1958 fr_value_box_t a, b, dst;
1959
1961
1962 fr_value_box(&a, (uint32_t) 10, false);
1963 fr_value_box(&b, (int32_t) -3, false);
1964
1965 /* uint32 + int32 should upcast to int64 */
1967 TEST_CHECK(dst.type == FR_TYPE_INT64);
1968 TEST_CHECK(dst.vb_int64 == 7);
1969 TEST_MSG("Expected 7, got %" PRId64, dst.vb_int64);
1970}
1971
1972/*
1973 * Tainted propagation from b
1974 */
1975static void test_tainted_from_b(void)
1976{
1977 fr_value_box_t a, b, dst;
1978
1979 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
1980
1981 fr_value_box(&a, (uint32_t) 10, false);
1982 fr_value_box(&b, (uint32_t) 20, true);
1983
1985 TEST_CHECK(dst.vb_uint32 == 30);
1986 TEST_CHECK(dst.tainted == true);
1987 TEST_MSG("Expected tainted to be true when b is tainted");
1988}
1989
1990static void test_tainted_neither(void)
1991{
1992 fr_value_box_t a, b, dst;
1993
1994 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
1995
1996 fr_value_box(&a, (uint32_t) 10, false);
1997 fr_value_box(&b, (uint32_t) 20, false);
1998
2000 TEST_CHECK(dst.tainted == false);
2001 TEST_MSG("Expected tainted to be false when neither is tainted");
2002}
2003
2004/*
2005 * IPv4 prefix add overflow
2006 */
2008{
2009 fr_value_box_t a, b, dst;
2010
2011 fr_value_box_init(&a, FR_TYPE_IPV4_PREFIX, NULL, false);
2012 fr_value_box_init(&dst, FR_TYPE_IPV4_ADDR, NULL, false);
2013
2014 /* 10.0.0.0/24 + 256 = overflow (only 256 addresses in /24, 0..255) */
2015 a.vb_ip.af = AF_INET;
2016 a.vb_ipv4addr = htonl(0x0a000000); /* 10.0.0.0 */
2017 a.vb_ip.prefix = 24;
2018 fr_value_box(&b, (uint32_t) 256, false);
2019
2021}
2022
2023/*
2024 * IPv4 and with all-ones mask
2025 */
2027{
2028 fr_value_box_t a, b, dst;
2029
2030 fr_value_box_init(&a, FR_TYPE_IPV4_ADDR, NULL, false);
2031 fr_value_box_init(&dst, FR_TYPE_IPV4_PREFIX, NULL, false);
2032
2033 a.vb_ip.af = AF_INET;
2034 a.vb_ipv4addr = htonl(0xc0a80164); /* 192.168.1.100 */
2035 a.vb_ip.prefix = 32;
2036 fr_value_box(&b, (uint32_t) 0xffffffff, false);
2037
2039 TEST_CHECK(ntohl(dst.vb_ipv4addr) == 0xc0a80164);
2040 TEST_CHECK(dst.vb_ip.prefix == 32);
2041}
2042
2044{
2045 fr_value_box_t a, b, dst;
2046
2047 fr_value_box_init(&a, FR_TYPE_IPV4_ADDR, NULL, false);
2048 fr_value_box_init(&dst, FR_TYPE_IPV4_PREFIX, NULL, false);
2049
2050 a.vb_ip.af = AF_INET;
2051 a.vb_ipv4addr = htonl(0xc0a80164);
2052 a.vb_ip.prefix = 32;
2053 fr_value_box(&b, (uint32_t) 0, false);
2054
2056 TEST_CHECK(ntohl(dst.vb_ipv4addr) == 0);
2057 TEST_CHECK(dst.vb_ip.prefix == 0);
2058}
2059
2060/*
2061 * Auto type hint for rshift
2062 */
2064{
2065 fr_value_box_t a, b, dst;
2066
2068
2069 fr_value_box(&a, (uint32_t) 0x100, false);
2070 fr_value_box(&b, (uint32_t) 4, false);
2071
2072 /* auto type hint for rshift should keep the LHS type */
2074 TEST_CHECK(dst.type == FR_TYPE_UINT32);
2075 TEST_CHECK(dst.vb_uint32 == 0x10);
2076 TEST_MSG("Expected 0x10, got 0x%x", dst.vb_uint32);
2077}
2078
2079/*
2080 * String comparison
2081 */
2082static void test_cmp_string(void)
2083{
2084 fr_value_box_t a, b, dst;
2085
2086 fr_value_box_init(&a, FR_TYPE_STRING, NULL, false);
2087 fr_value_box_init(&b, FR_TYPE_STRING, NULL, false);
2088 fr_value_box_init(&dst, FR_TYPE_BOOL, NULL, false);
2089
2090 fr_value_box_strdup(autofree, &a, NULL, "abc", false);
2091 fr_value_box_strdup(autofree, &b, NULL, "abc", false);
2092
2094 TEST_CHECK(dst.vb_bool == true);
2095
2097 fr_value_box_strdup(autofree, &b, NULL, "def", false);
2098
2100 TEST_CHECK(dst.vb_bool == true);
2101
2104}
2105
2106/*
2107 * IPv4 prefix + integer = address
2108 */
2109static void test_ipv4_prefix_add(void)
2110{
2111 fr_value_box_t a, b, dst;
2112
2113 fr_value_box_init(&a, FR_TYPE_IPV4_PREFIX, NULL, false);
2114 fr_value_box_init(&dst, FR_TYPE_IPV4_ADDR, NULL, false);
2115
2116 /* 192.168.0.0/24 + 1 = 192.168.0.1 */
2117 a.vb_ip.af = AF_INET;
2118 a.vb_ipv4addr = htonl(0xc0a80000); /* 192.168.0.0 */
2119 a.vb_ip.prefix = 24;
2120 fr_value_box(&b, (uint32_t) 1, false);
2121
2123 TEST_CHECK(ntohl(dst.vb_ipv4addr) == 0xc0a80001); /* 192.168.0.1 */
2124 TEST_MSG("Expected 192.168.0.1, got 0x%08x", ntohl(dst.vb_ipv4addr));
2125}
2126
2127/*
2128 * IPv4 address AND mask = prefix
2129 */
2131{
2132 fr_value_box_t a, b, dst;
2133
2134 fr_value_box_init(&a, FR_TYPE_IPV4_ADDR, NULL, false);
2135 fr_value_box_init(&dst, FR_TYPE_IPV4_PREFIX, NULL, false);
2136
2137 /* 192.168.1.100 & 0xffffff00 = 192.168.1.0/24 */
2138 a.vb_ip.af = AF_INET;
2139 a.vb_ipv4addr = htonl(0xc0a80164); /* 192.168.1.100 */
2140 a.vb_ip.prefix = 32;
2141 fr_value_box(&b, (uint32_t) 0xffffff00, false);
2142
2144 TEST_CHECK(ntohl(dst.vb_ipv4addr) == 0xc0a80100); /* 192.168.1.0 */
2145 TEST_CHECK(dst.vb_ip.prefix == 24);
2146 TEST_MSG("Expected prefix 24, got %u", dst.vb_ip.prefix);
2147}
2148
2149/*
2150 * Tainted flag propagation
2151 */
2153{
2154 fr_value_box_t a, b, dst;
2155
2156 fr_value_box_init(&dst, FR_TYPE_UINT32, NULL, false);
2157
2158 fr_value_box(&a, (uint32_t) 10, true);
2159 fr_value_box(&b, (uint32_t) 20, false);
2160
2162 TEST_CHECK(dst.vb_uint32 == 30);
2163 TEST_CHECK(dst.tainted == true);
2164 TEST_MSG("Expected tainted to be true");
2165}
2166
2168 /* uint32 arithmetic */
2169 { "uint32_add", test_uint32_add },
2170 { "uint32_sub", test_uint32_sub },
2171 { "uint32_mul", test_uint32_mul },
2172 { "uint32_div", test_uint32_div },
2173 { "uint32_mod", test_uint32_mod },
2174 { "uint32_and", test_uint32_and },
2175 { "uint32_or", test_uint32_or },
2176 { "uint32_xor", test_uint32_xor },
2177 { "uint32_shift", test_uint32_shift },
2178 { "uint32_div_zero", test_uint32_div_zero },
2179
2180 /* uint8 */
2181 { "uint8_add", test_uint8_add },
2182 { "uint8_overflow", test_uint8_overflow },
2183
2184 /* uint16 */
2185 { "uint16_add", test_uint16_add },
2186 { "uint16_overflow", test_uint16_overflow },
2187
2188 /* uint64 */
2189 { "uint64_and", test_uint64_and },
2190 { "uint64_or", test_uint64_or },
2191 { "uint64_xor", test_uint64_xor },
2192 { "uint64_shift", test_uint64_shift },
2193 { "uint64_shift_too_large", test_uint64_shift_too_large },
2194 { "uint64_mod", test_uint64_mod },
2195 { "uint64_div", test_uint64_div },
2196 { "uint64_div_zero", test_uint64_div_zero },
2197
2198 /* signed integers */
2199 { "int8_add", test_int8_add },
2200 { "int8_sub", test_int8_sub },
2201 { "int16_add", test_int16_add },
2202 { "int32_add", test_int32_add },
2203 { "int32_sub", test_int32_sub },
2204 { "int32_mul", test_int32_mul },
2205 { "int32_div", test_int32_div },
2206 { "int32_mod", test_int32_mod },
2207 { "int64_div_zero", test_int64_div_zero },
2208 { "int64_and", test_int64_and },
2209 { "int64_or", test_int64_or },
2210 { "int64_xor", test_int64_xor },
2211 { "int64_shift", test_int64_shift },
2212 { "int64_shift_too_large", test_int64_shift_too_large },
2213 { "int64_mod", test_int64_mod },
2214
2215 /* booleans */
2216 { "bool_and", test_bool_and },
2217 { "bool_or", test_bool_or },
2218 { "bool_xor", test_bool_xor },
2219 { "bool_add", test_bool_add },
2220 { "bool_sub", test_bool_sub },
2221 { "bool_mul", test_bool_mul },
2222
2223 /* float64 */
2224 { "float64_add", test_float64_add },
2225 { "float64_sub", test_float64_sub },
2226 { "float64_mul", test_float64_mul },
2227 { "float64_div", test_float64_div },
2228 { "float64_div_zero", test_float64_div_zero },
2229 { "float64_mod", test_float64_mod },
2230 { "float64_mod_zero", test_float64_mod_zero },
2231
2232 /* float32 */
2233 { "float32_add", test_float32_add },
2234 { "float32_sub", test_float32_sub },
2235 { "float32_mul", test_float32_mul },
2236 { "float32_div", test_float32_div },
2237 { "float32_div_zero", test_float32_div_zero },
2238 { "float32_mod", test_float32_mod },
2239 { "float32_mod_zero", test_float32_mod_zero },
2240
2241 /* strings */
2242 { "string_add", test_string_add },
2243 { "string_add_empty", test_string_add_empty },
2244 { "string_sub", test_string_sub },
2245 { "string_sub_not_suffix", test_string_sub_not_suffix },
2246 { "string_sub_too_long", test_string_sub_too_long },
2247 { "string_xor_prepend", test_string_xor_prepend },
2248 { "string_rshift", test_string_rshift },
2249 { "string_lshift", test_string_lshift },
2250 { "string_rshift_too_large", test_string_rshift_too_large },
2251 { "string_lshift_too_large", test_string_lshift_too_large },
2252
2253 /* octets */
2254 { "octets_add", test_octets_add },
2255 { "octets_sub", test_octets_sub },
2256 { "octets_sub_not_suffix", test_octets_sub_not_suffix },
2257 { "octets_sub_too_long", test_octets_sub_too_long },
2258 { "octets_and", test_octets_and },
2259 { "octets_or", test_octets_or },
2260 { "octets_xor", test_octets_xor },
2261 { "octets_length_mismatch", test_octets_length_mismatch },
2262 { "octets_rshift", test_octets_rshift },
2263 { "octets_lshift", test_octets_lshift },
2264 { "octets_rshift_too_large", test_octets_rshift_too_large },
2265 { "octets_lshift_too_large", test_octets_lshift_too_large },
2266
2267 /* comparisons */
2268 { "cmp_eq", test_cmp_eq },
2269 { "cmp_ne", test_cmp_ne },
2270 { "cmp_lt", test_cmp_lt },
2271 { "cmp_gt", test_cmp_gt },
2272 { "cmp_le", test_cmp_le },
2273 { "cmp_ge", test_cmp_ge },
2274 { "cmp_eq_type", test_cmp_eq_type },
2275 { "auto_type_hint_rshift", test_auto_type_hint_rshift },
2276 { "cmp_different_types", test_cmp_different_types },
2277 { "cmp_string", test_cmp_string },
2278
2279 /* unary */
2280 { "unary_increment", test_unary_increment },
2281 { "unary_increment_uint8", test_unary_increment_uint8 },
2282 { "unary_increment_overflow", test_unary_increment_overflow },
2283 { "unary_increment_int64", test_unary_increment_int64 },
2284 { "unary_increment_float64", test_unary_increment_float64 },
2285 { "unary_complement", test_unary_complement },
2286 { "unary_complement_uint16", test_unary_complement_uint16 },
2287 { "unary_complement_uint32", test_unary_complement_uint32 },
2288 { "unary_complement_uint64", test_unary_complement_uint64 },
2289 { "unary_complement_int32", test_unary_complement_int32 },
2290 { "unary_negate", test_unary_negate },
2291 { "unary_negate_float64", test_unary_negate_float64 },
2292 { "unary_not", test_unary_not },
2293 { "unary_not_bool", test_unary_not_bool },
2294
2295 /* assignment */
2296 { "assign_add", test_assign_add },
2297 { "assign_sub", test_assign_sub },
2298 { "assign_mul", test_assign_mul },
2299 { "assign_div", test_assign_div },
2300 { "assign_and", test_assign_and },
2301 { "assign_or", test_assign_or },
2302 { "assign_xor", test_assign_xor },
2303 { "assign_rshift", test_assign_rshift },
2304 { "assign_lshift", test_assign_lshift },
2305 { "assign_set", test_assign_set },
2306 { "assign_self", test_assign_self },
2307
2308 /* type coercion */
2309 { "mixed_uint8_uint32", test_mixed_uint8_uint32 },
2310 { "mixed_uint32_int32", test_mixed_uint32_int32 },
2311 { "auto_type_hint", test_auto_type_hint },
2312 { "auto_type_hint_sub", test_auto_type_hint_sub },
2313 { "auto_type_hint_lshift", test_auto_type_hint_lshift },
2314
2315 /* overflow / underflow */
2316 { "uint64_overflow", test_uint64_overflow },
2317 { "uint64_underflow", test_uint64_underflow },
2318 { "uint64_mul_overflow", test_uint64_mul_overflow },
2319 { "int64_overflow", test_int64_overflow },
2320 { "int64_underflow", test_int64_underflow },
2321
2322 /* IPv4 */
2323 { "ipv4_prefix_add", test_ipv4_prefix_add },
2324 { "ipv4_prefix_add_overflow", test_ipv4_prefix_add_overflow },
2325 { "ipv4_addr_and_mask", test_ipv4_addr_and_mask },
2326 { "ipv4_addr_and_all_ones", test_ipv4_addr_and_all_ones },
2327 { "ipv4_addr_and_zero", test_ipv4_addr_and_zero },
2328
2329 /* misc */
2330 { "tainted_propagation", test_tainted_propagation },
2331 { "tainted_from_b", test_tainted_from_b },
2332 { "tainted_neither", test_tainted_neither },
2333
2335};
#define TEST_CHECK(cond)
Definition acutest.h:87
#define TEST_TERMINATOR
Definition acutest.h:64
#define TEST_MSG(...)
Definition acutest.h:217
int fr_value_calc_assignment_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src)
Calculate DST OP SRC.
Definition calc.c:2497
int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint, fr_value_box_t const *a, fr_token_t op, fr_value_box_t const *b)
Calculate DST = A OP B.
Definition calc.c:1991
int fr_value_calc_unary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t op, fr_value_box_t const *src)
Calculate unary operations.
Definition calc.c:2558
static void test_assign_xor(void)
static void test_unary_complement_uint16(void)
static void test_tainted_propagation(void)
static void test_float64_mod(void)
Definition calc_tests.c:460
static void test_uint32_xor(void)
Definition calc_tests.c:146
static void test_octets_and(void)
Definition calc_tests.c:664
static void test_unary_complement(void)
Definition calc_tests.c:924
static void test_assign_sub(void)
Definition calc_tests.c:982
static void test_uint64_overflow(void)
static void test_uint64_mod(void)
static void test_ipv4_prefix_add_overflow(void)
static void test_uint64_xor(void)
TEST_LIST
static void test_assign_or(void)
static void test_uint32_div_zero(void)
Definition calc_tests.c:184
static void test_ipv4_addr_and_mask(void)
static void test_uint64_mul_overflow(void)
static void test_int64_div_zero(void)
Definition calc_tests.c:287
static void test_uint32_sub(void)
Definition calc_tests.c:62
static void test_unary_increment_int64(void)
static void test_ipv4_addr_and_all_ones(void)
static void test_uint64_div(void)
static void test_unary_not(void)
Definition calc_tests.c:950
static void test_auto_type_hint_lshift(void)
static void test_bool_mul(void)
static void test_float32_mod_zero(void)
static TALLOC_CTX * autofree
Definition calc_tests.c:28
static void test_string_rshift_too_large(void)
static void test_auto_type_hint(void)
static void test_octets_lshift(void)
Definition calc_tests.c:762
static void test_int16_add(void)
static void test_uint32_and(void)
Definition calc_tests.c:118
static void test_ipv4_addr_and_zero(void)
static void test_assign_self(void)
static void test_int8_sub(void)
static void test_mixed_uint8_uint32(void)
static void test_mixed_uint32_int32(void)
static void test_cmp_ge(void)
Definition calc_tests.c:871
static void test_uint32_or(void)
Definition calc_tests.c:132
static void test_string_add_empty(void)
static void test_unary_complement_int32(void)
static void test_int32_mul(void)
Definition calc_tests.c:259
static void test_uint8_add(void)
Definition calc_tests.c:201
static void test_tainted_from_b(void)
static void test_tainted_neither(void)
static void test_uint32_shift(void)
Definition calc_tests.c:160
static void test_assign_and(void)
static void test_uint32_add(void)
Definition calc_tests.c:48
static void test_bool_sub(void)
Definition calc_tests.c:371
static void test_assign_lshift(void)
static void test_octets_sub_too_long(void)
static void test_int32_mod(void)
static void test_uint32_div(void)
Definition calc_tests.c:90
static void test_assign_mul(void)
static void test_octets_rshift_too_large(void)
static void test_float64_mul(void)
Definition calc_tests.c:420
static void test_float32_sub(void)
static void test_assign_add(void)
Definition calc_tests.c:969
static void test_auto_type_hint_sub(void)
static void test_uint64_or(void)
static void test_string_sub_too_long(void)
static void test_string_xor_prepend(void)
Definition calc_tests.c:564
static void test_uint32_mul(void)
Definition calc_tests.c:76
static void test_cmp_ne(void)
Definition calc_tests.c:803
static void test_assign_div(void)
static void test_uint16_add(void)
static void test_assign_rshift(void)
static void test_uint8_overflow(void)
Definition calc_tests.c:215
static void test_bool_and(void)
Definition calc_tests.c:302
static void test_cmp_eq_type(void)
Definition calc_tests.c:888
static void test_float32_add(void)
Definition calc_tests.c:477
static void test_uint64_shift(void)
static void test_float64_sub(void)
Definition calc_tests.c:406
static void test_float64_mod_zero(void)
static void test_cmp_gt(void)
Definition calc_tests.c:837
static void test_uint64_underflow(void)
static void test_int32_sub(void)
Definition calc_tests.c:245
static void test_unary_negate_float64(void)
static void test_string_add(void)
Definition calc_tests.c:506
static void test_string_lshift(void)
Definition calc_tests.c:603
static void test_float64_div_zero(void)
Definition calc_tests.c:448
static void test_unary_not_bool(void)
static void test_float32_mod(void)
static void test_bool_xor(void)
Definition calc_tests.c:336
static void test_cmp_different_types(void)
static void test_cmp_eq(void)
Definition calc_tests.c:783
static void test_string_sub_not_suffix(void)
Definition calc_tests.c:546
static void test_cmp_string(void)
static void test_octets_or(void)
Definition calc_tests.c:684
static void test_octets_xor(void)
Definition calc_tests.c:704
static void test_string_sub(void)
Definition calc_tests.c:526
static void test_unary_complement_uint64(void)
static void test_float64_div(void)
Definition calc_tests.c:434
static void test_cmp_le(void)
Definition calc_tests.c:854
static void test_int32_div(void)
Definition calc_tests.c:273
static void test_unary_complement_uint32(void)
static void test_uint16_overflow(void)
static void test_octets_length_mismatch(void)
Definition calc_tests.c:724
static void test_float32_mul(void)
static void test_int8_add(void)
static void test_cmp_lt(void)
Definition calc_tests.c:820
static void test_int64_underflow(void)
static void test_int64_xor(void)
static void test_unary_increment(void)
Definition calc_tests.c:911
static void test_int64_or(void)
static void test_assign_set(void)
Definition calc_tests.c:995
static void test_unary_increment_float64(void)
static void test_bool_add(void)
Definition calc_tests.c:353
static void test_float32_div_zero(void)
Definition calc_tests.c:491
static void test_int64_overflow(void)
static void test_init(void)
Definition calc_tests.c:30
static void test_octets_add(void)
Definition calc_tests.c:624
static void test_int64_shift_too_large(void)
static void test_bool_or(void)
Definition calc_tests.c:319
static void test_uint64_div_zero(void)
static void test_auto_type_hint_rshift(void)
static void test_uint64_and(void)
static void test_float64_add(void)
Definition calc_tests.c:392
static void test_uint64_shift_too_large(void)
static void test_unary_negate(void)
Definition calc_tests.c:937
static void test_uint32_mod(void)
Definition calc_tests.c:104
static void test_octets_sub_not_suffix(void)
static void test_ipv4_prefix_add(void)
static void test_octets_sub(void)
Definition calc_tests.c:644
static void test_unary_increment_uint8(void)
static void test_int32_add(void)
Definition calc_tests.c:231
static void test_string_rshift(void)
Definition calc_tests.c:585
static void test_float32_div(void)
static void test_octets_lshift_too_large(void)
static void test_string_lshift_too_large(void)
static void test_int64_mod(void)
static void test_unary_increment_overflow(void)
static void test_octets_rshift(void)
Definition calc_tests.c:744
static void test_int64_and(void)
static void test_int64_shift(void)
#define fr_exit_now(_x)
Exit without calling atexit() handlers, producing a log message in debug builds.
Definition debug.h:236
unsigned short uint16_t
@ FR_TYPE_FLOAT32
Single precision floating point.
@ FR_TYPE_IPV4_ADDR
32 Bit IPv4 Address.
@ FR_TYPE_INT8
8 Bit signed integer.
@ FR_TYPE_STRING
String of printable characters.
@ FR_TYPE_NULL
Invalid (uninitialised) attribute type.
@ FR_TYPE_UINT16
16 Bit unsigned integer.
@ FR_TYPE_INT64
64 Bit signed integer.
@ FR_TYPE_INT16
16 Bit signed integer.
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_INT32
32 Bit signed integer.
@ FR_TYPE_UINT64
64 Bit unsigned integer.
@ FR_TYPE_IPV4_PREFIX
IPv4 Prefix.
@ FR_TYPE_BOOL
A truth value.
@ FR_TYPE_OCTETS
Raw octets.
@ FR_TYPE_FLOAT64
Double precision floating point.
unsigned int uint32_t
unsigned char uint8_t
#define talloc_autofree_context
The original function is deprecated, so replace it with our version.
Definition talloc.h:48
#define T_OP_XOR_EQ
Definition token.h:84
@ T_AND
Definition token.h:53
@ T_OP_SUB_EQ
Definition token.h:68
@ T_SUB
Definition token.h:50
@ T_RSHIFT
Definition token.h:60
@ T_NOT
Definition token.h:55
@ T_OP_DIV_EQ
Definition token.h:70
@ T_XOR
Definition token.h:56
@ T_DIV
Definition token.h:52
@ T_MOD
Definition token.h:58
@ T_OP_AND_EQ
Definition token.h:72
@ T_OP_EQ
Definition token.h:81
@ T_OP_MUL_EQ
Definition token.h:69
@ T_COMPLEMENT
Definition token.h:57
@ T_ADD
Definition token.h:49
@ T_OP_SET
Definition token.h:82
@ T_OP_NE
Definition token.h:95
@ T_OP_ADD_EQ
Definition token.h:67
@ T_OP_LSHIFT_EQ
Definition token.h:75
@ T_LSHIFT
Definition token.h:61
@ T_OP_RSHIFT_EQ
Definition token.h:74
@ T_OP_CMP_EQ_TYPE
Definition token.h:105
@ T_OP_CMP_EQ
Definition token.h:104
@ T_OP_INCRM
Definition token.h:111
@ T_MUL
Definition token.h:51
@ T_OP_LE
Definition token.h:98
@ T_OP_GE
Definition token.h:96
@ T_OP_GT
Definition token.h:97
@ T_OP_OR_EQ
Definition token.h:71
@ T_OP_LT
Definition token.h:99
@ T_OR
Definition token.h:54
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
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:4604
void fr_value_box_clear(fr_value_box_t *data)
Clear/free any existing value and metadata.
Definition value.c:4362
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:5064
#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
#define fr_value_box_init(_vb, _type, _enumv, _tainted)
Initialise a fr_value_box_t.
Definition value.h:610