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