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