]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
add preliminary support for and/or
authorAlan T. DeKok <aland@freeradius.org>
Sat, 20 Nov 2021 19:59:15 +0000 (14:59 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 20 Nov 2021 19:59:15 +0000 (14:59 -0500)
we likely also want to allow

ipaddr AND integer -> ipv4prefix

tho that' a little more work to figure stuff out

src/bin/unit_test_attribute.c
src/lib/util/calc.c
src/lib/util/token.c
src/lib/util/token.h
src/tests/unit/calc.txt

index ad289edd0d16c152c3d21a4d323b123a6ff1bfd8..f11bdad709894aa73335816f9dd72230b649e726 100644 (file)
@@ -1174,6 +1174,8 @@ static const fr_token_t token2op[UINT8_MAX + 1] = {
        [ '/' ] = T_DIV,
        [ '^' ] = T_OP_PREPEND,
        [ '.' ] = T_ADD,
+       [ '&' ] = T_AND,
+       [ '|' ] = T_OR,
 };
 
 /** Perform calculations
index a6af2dea811c0e38b55ef970374efb2fc68ea674..ec0b9446233bd9d199e110bb89a2b32bddbd5486 100644 (file)
@@ -403,6 +403,38 @@ static int calc_octets(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t cons
                fr_value_box_memdup_shallow(dst, dst->enumv, buf, len, a->tainted | b->tainted);
                break;
 
+       case T_AND:
+               if (a->vb_length != b->vb_length) {
+               length_error:
+                       fr_strerror_const("Cannot perform operation on strings of different length");
+                       return -1;
+               }
+
+               buf = talloc_array(ctx, uint8_t, a->vb_length);
+               if (!buf) goto oom;
+
+               for (len = 0; len < a->vb_length; len++) {
+                       buf[len] = a->vb_octets[len] & b->vb_octets[len];
+               }
+
+               fr_value_box_clear_value(dst);
+               fr_value_box_memdup_shallow(dst, dst->enumv, buf, a->vb_length, a->tainted | b->tainted);
+               break;
+
+       case T_OR:
+               if (a->vb_length != b->vb_length) goto length_error;
+
+               buf = talloc_array(ctx, uint8_t, a->vb_length);
+               if (!buf) goto oom;
+
+               for (len = 0; len < a->vb_length; len++) {
+                       buf[len] = a->vb_octets[len] | b->vb_octets[len];
+               }
+
+               fr_value_box_clear_value(dst);
+               fr_value_box_memdup_shallow(dst, dst->enumv, buf, a->vb_length, a->tainted | b->tainted);
+               break;
+
        default:
                return ERR_INVALID;     /* invalid operator */
        }
@@ -813,6 +845,14 @@ static int calc_float64(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_bo
        case T_DIV: \
                dst->vb_ ## _t = in1->vb_ ## _t /  in2->vb_ ## _t; \
                break; \
+ \
+       case T_AND: \
+               dst->vb_ ## _t = in1->vb_ ## _t &  in2->vb_ ## _t; \
+               break; \
+ \
+       case T_OR: \
+               dst->vb_ ## _t = in1->vb_ ## _t |  in2->vb_ ## _t; \
+               break; \
  \
        default: \
                return ERR_INVALID; \
@@ -1126,6 +1166,8 @@ int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint
        case T_SUB:
        case T_MUL:
        case T_DIV:
+       case T_AND:
+       case T_OR:
        case T_OP_PREPEND:
                fr_assert(hint != FR_TYPE_NULL);
 
index 2950cde0df1af26feea6ba697af5abaf6b9c4e2d..706cb400acd3980ecc4d0775a179e79d0df47d34 100644 (file)
@@ -84,6 +84,8 @@ char const *fr_tokens[T_TOKEN_LAST] = {
        [T_SUB]      = "-",
        [T_MUL]      = "*",
        [T_DIV]      = "/",
+       [T_AND]      = "&",
+       [T_OR]       = "|",
 
        [T_OP_INCRM] = "++",
 
@@ -169,6 +171,8 @@ const bool fr_binary_op[T_TOKEN_LAST] = {
        T(SUB),
        T(MUL),
        T(DIV),
+       T(AND),
+       T(OR),
 };
 
 
index 6bf29f0eb882484a6dcdede0285b11eee80aa7f4..13519353b9278fd9f4f7f39a9fb9634f46412a3d 100644 (file)
@@ -49,6 +49,8 @@ typedef enum fr_token {
        T_SUB,                          /* - */
        T_MUL,                          /* * */
        T_DIV,                          /* / */
+       T_AND,                          /* & */
+       T_OR,                           /* | */
 
        /*
         *      Only used by LDAP ???
index 25537ca25cc4b47a8367e1991274bb33df49d7b4..a410c5232bc87e617a0f1a2c045b2d8f1870bc69 100644 (file)
@@ -2,6 +2,10 @@
 #  Calculate various thingies.
 #
 
+######################################################################
+#
+#  integers
+#
 calc uint8 255 + uint8 255 -> uint8
 match Value overflows/underflows when calculating answer for uint8
 
@@ -19,6 +23,9 @@ match 13
 calc int32 -1 + uint8 14 -> int16
 match 13
 
+calc int8 0x7f & uint8 0x40 -> uint8
+match 64
+
 #
 #  Intermediate values are too large for destination, but the
 #  resulting value can fit.
@@ -26,6 +33,18 @@ match 13
 calc uint32 1000 - uint32 999 -> uint8
 match 1
 
+# this can be cast
+calc string "1" < uint32 2 -> bool
+match yes
+
+# this can't
+calc string "stuff" < uint32 2 -> bool
+match Failed parsing string as type 'uint32'
+
+######################################################################
+#
+#  strings
+#
 # string append
 calc string "a" . string "b" -> string
 match ab
@@ -34,6 +53,10 @@ match ab
 calc string "ab" - string "b" -> string
 match a
 
+######################################################################
+#
+#  octets
+#
 # octets prepend
 calc octets "a" ^ octets "b" -> octets
 match 0x6261
@@ -46,7 +69,20 @@ match 0x6162
 calc octets "ab" - octets "b" -> octets
 match 0x61
 
+calc octets "a" & octets "b" -> octets
+match 0x60
+
+calc octets "a" | octets "b" -> octets
+match 0x63
+
+# we can "fake out" structs by just appending stuff
+calc ipaddr 127.0.0.1 . ipaddr 127.0.0.2 -> octets
+match 0x7f0000017f000002
 
+######################################################################
+#
+#  times and dates
+#
 # time deltas
 calc time_delta 1 + time_delta 2 -> time_delta
 match 3
@@ -68,17 +104,10 @@ match Jan 10 1970 00:00:00 UTC
 calc date "Jan 11 1970 00:00:00 UTC" < date "Jan 1 1970 00:00:00 UTC"
 match no
 
-# we can "fake out" structs by just appending stuff
-calc ipaddr 127.0.0.1 . ipaddr 127.0.0.2 -> octets
-match 0x7f0000017f000002
-
-# this can be cast
-calc string "1" < uint32 2 -> bool
-match yes
-
-# this can't
-calc string "stuff" < uint32 2 -> bool
-match Failed parsing string as type 'uint32'
+######################################################################
+#
+#  ip addresses and prefixes
+#
 
 #
 # make an IP out of a prefix and an offset
@@ -107,4 +136,4 @@ calc string "2" += string "test"
 match 2test
 
 count
-match 48
+match 54