From: Alan T. DeKok Date: Sat, 20 Nov 2021 16:09:35 +0000 (-0500) Subject: subtraction is the inverse of addition X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=41df5a7dca3d05137b9a4354a760553708f94dec;p=thirdparty%2Ffreeradius-server.git subtraction is the inverse of addition --- diff --git a/src/lib/util/calc.c b/src/lib/util/calc.c index 8f65ab0f05b..a9a0806313b 100644 --- a/src/lib/util/calc.c +++ b/src/lib/util/calc.c @@ -379,6 +379,31 @@ 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_SUB: + /* + * The inverse of add! + */ + if (a->vb_length < b->vb_length) { + fr_strerror_const("Suffix to remove is longer than input string"); + return -1; + } + + if (memcmp(a->vb_octets + a->vb_length - b->vb_length, b->vb_strvalue, b->vb_length) != 0) { + fr_strerror_const("Right side is not a suffix of the input string"); + return -1; + } + + len = a->vb_length - b->vb_length; + buf = talloc_array(ctx, uint8_t, len); + if (!buf) goto oom; + + memcpy(buf, a->vb_strvalue, len); + buf[len] = '\0'; + + fr_value_box_clear_value(dst); + fr_value_box_memdup_shallow(dst, dst->enumv, buf, len, a->tainted | b->tainted); + break; + default: return ERR_INVALID; /* invalid operator */ } @@ -438,6 +463,31 @@ static int calc_string(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t cons fr_value_box_strdup_shallow(dst, dst->enumv, buf, a->tainted | b->tainted); break; + case T_SUB: + /* + * The inverse of add! + */ + if (a->vb_length < b->vb_length) { + fr_strerror_const("Suffix to remove is longer than input string"); + return -1; + } + + if (memcmp(a->vb_strvalue + a->vb_length - b->vb_length, b->vb_strvalue, b->vb_length) != 0) { + fr_strerror_const("Right side is not a suffix of the input string"); + return -1; + } + + len = a->vb_length - b->vb_length; + buf = talloc_array(ctx, char, len + 1); + if (!buf) goto oom; + + memcpy(buf, a->vb_strvalue, len); + buf[len] = '\0'; + + fr_value_box_clear_value(dst); + fr_value_box_strdup_shallow(dst, dst->enumv, buf, a->tainted | b->tainted); + break; + default: return ERR_INVALID; /* invalid operator */ } diff --git a/src/tests/unit/calc.txt b/src/tests/unit/calc.txt index 0efe2323ad8..25537ca25cc 100644 --- a/src/tests/unit/calc.txt +++ b/src/tests/unit/calc.txt @@ -30,9 +30,22 @@ match 1 calc string "a" . string "b" -> string match ab -# string prepend -calc string "a" ^ string "b" -> string -match ba +# string subtraction is the inverse of addition! +calc string "ab" - string "b" -> string +match a + +# octets prepend +calc octets "a" ^ octets "b" -> octets +match 0x6261 + +# octets append +calc octets "a" . octets "b" -> octets +match 0x6162 + +# octets subtraction is the inverse of addition! +calc octets "ab" - octets "b" -> octets +match 0x61 + # time deltas calc time_delta 1 + time_delta 2 -> time_delta @@ -94,4 +107,4 @@ calc string "2" += string "test" match 2test count -match 42 +match 48