From: Alan T. DeKok Date: Wed, 19 Jan 2022 16:28:07 +0000 (-0500) Subject: add XOR X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=dc73b7062a3fc88de393b87cc9aed4fbefe6cd88;p=thirdparty%2Ffreeradius-server.git add XOR --- diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index 4ce1ed3050..bfbdcd794e 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -1173,7 +1173,7 @@ static const fr_token_t token2op[UINT8_MAX + 1] = { [ '-' ] = T_SUB, [ '*' ] = T_MUL, [ '/' ] = T_DIV, - [ '^' ] = T_OP_PREPEND, + [ '^' ] = T_XOR, [ '.' ] = T_ADD, [ '&' ] = T_AND, [ '|' ] = T_OR, diff --git a/src/lib/util/calc.c b/src/lib/util/calc.c index cd2b2c3b34..d077cafa50 100644 --- a/src/lib/util/calc.c +++ b/src/lib/util/calc.c @@ -305,6 +305,10 @@ static int calc_bool(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t dst->vb_bool = a->vb_bool | b->vb_bool; break; + case T_XOR: + dst->vb_bool = a->vb_bool ^ b->vb_bool; + break; + default: return ERR_INVALID; } @@ -523,6 +527,19 @@ 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, a->vb_length, a->tainted | b->tainted); break; + case T_XOR: + 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_memdup_shallow(dst, dst->enumv, buf, a->vb_length, a->tainted | b->tainted); + break; + case T_RSHIFT: if (b->vb_uint32 > a->vb_length) return ERR_UNDERFLOW; @@ -1067,6 +1084,10 @@ static int calc_float64(UNUSED TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_bo case T_OR: \ dst->vb_ ## _t = in1->vb_ ## _t | in2->vb_ ## _t; \ break; \ + \ + case T_XOR: \ + dst->vb_ ## _t = in1->vb_ ## _t ^ in2->vb_ ## _t; \ + break; \ \ case T_RSHIFT: \ if (in2->vb_uint8 > (8 * sizeof(in1->vb_ ## _t))) return ERR_UNDERFLOW; \ @@ -1275,6 +1296,7 @@ int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint case T_DIV: case T_AND: case T_OR: + case T_XOR: case T_RSHIFT: case T_LSHIFT: if (a->type == b->type) { @@ -1379,6 +1401,7 @@ int fr_value_calc_binary_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_type_t hint case T_DIV: case T_AND: case T_OR: + case T_XOR: case T_RSHIFT: case T_LSHIFT: fr_assert(hint != FR_TYPE_NULL); @@ -1471,6 +1494,10 @@ int fr_value_calc_assignment_op(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_token_t rcode = fr_value_calc_binary_op(ctx, &out, dst->type, dst, T_OR, src); break; + case T_OP_XOR_EQ: + rcode = fr_value_calc_binary_op(ctx, &out, dst->type, dst, T_XOR, src); + break; + case T_OP_RSHIFT_EQ: rcode = fr_value_calc_binary_op(ctx, &out, dst->type, dst, T_RSHIFT, src); break; diff --git a/src/lib/util/token.c b/src/lib/util/token.c index 4c13ad394c..e45abcb899 100644 --- a/src/lib/util/token.c +++ b/src/lib/util/token.c @@ -89,6 +89,7 @@ char const *fr_tokens[T_TOKEN_LAST] = { [T_AND] = "&", [T_OR] = "|", [T_NOT] = "!", + [T_XOR] = "^", [T_RSHIFT] = ">>", [T_LSHIFT] = "<<", diff --git a/src/lib/util/token.h b/src/lib/util/token.h index 3a9a1c77b5..a76fccb10a 100644 --- a/src/lib/util/token.h +++ b/src/lib/util/token.h @@ -55,6 +55,7 @@ typedef enum fr_token { T_AND, /* & */ T_OR, /* | */ T_NOT, /* ! */ + T_XOR, /* ^ */ T_RSHIFT, /* >> */ T_LSHIFT, /* << */ diff --git a/src/tests/unit/calc.txt b/src/tests/unit/calc.txt index 04505c285c..9b57b8e631 100644 --- a/src/tests/unit/calc.txt +++ b/src/tests/unit/calc.txt @@ -78,8 +78,8 @@ calc octets "a" | octets "b" -> octets match 0x63 # octets xor -#calc octets "a" ^ octets "b" -> octets -#match 0x03 +calc octets "a" ^ octets "b" -> octets +match 0x03 # we can "fake out" structs by just appending stuff calc ipaddr 127.0.0.1 . ipaddr 127.0.0.2 -> octets @@ -155,4 +155,4 @@ calc string "2" += string "test" match 2test count -match 62 +match 64