From: Alan T. DeKok Date: Sat, 27 Aug 2022 12:52:18 +0000 (-0400) Subject: make prepend work, and update doecs and tests to match X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8df2d3a77c3db0ef5fd49fe14008cbaa6bc7cdee;p=thirdparty%2Ffreeradius-server.git make prepend work, and update doecs and tests to match --- diff --git a/doc/antora/modules/reference/pages/unlang/edit.adoc b/doc/antora/modules/reference/pages/unlang/edit.adoc index d16dc720f71..34ce7d4237c 100644 --- a/doc/antora/modules/reference/pages/unlang/edit.adoc +++ b/doc/antora/modules/reference/pages/unlang/edit.adoc @@ -391,12 +391,18 @@ The operators also apply to variable-sized values. | := | Override the attribute with the contents with the __. If the attribute already exists, its value is over-written. If the attribute does not exist, it is created, and the contents set to thex value of the __ | += | Perform string append. The contents of the __ are appended to the __. | -= | Inverse of string append. The contents of the __ are deleted from from the __, if the `__` is a suffix of __ -| ^= | Perform logical "xor". The contents of the __ are "xor"ed with the contents of the __. Both strings must be of the same length. -| \|= | Perform logical "or". The value of the __ is "or"ed with the contents of the __. Both strings must be of the same length. -| &= | Perform logical "and". The value of the __ is "and"ed with the contents of the __. Both strings must be of the same length. -| <\<= | Perform left shift / truncation. The first __ bytes of __ are dropped. i.e. shifted off of the start of the string. -| >>= | Perform right shift / truncation. The last __ bytes of __ are dropped. i.e. shifted off of the end of the string. +| ^= | For `string`, performs a "prepend" operation. The contents of the __ are prepended to the __. This is the opposite of `+=`. +| | For `octets`, perform logical "xor". The value of the __ is "or"ed with the contents of the __. Both strings must be of the same length. +| \|= | Perform logical "or". The value of the __ is "or"ed with the contents of the __. Both strings must be of the same length. +| &= | Perform logical "and". The value of the __ is "and"ed with the contents of the __. Both strings must be of the same length. +| <\<= | Perform left shift / truncation. The first __ bytes of __ are dropped. i.e. shifted off of the start of the string. +| >>= | Perform right shift / truncation. The last __ bytes of __ are dropped. i.e. shifted off of the end of the string. |===== +Note that the `^=` operator behaves differently for `string` and +`octets`. The output of "xor"ing two strings is likely to be binary +data, and therefore not a printable string. As a result, it is more +useful for strings to have `^-` be a "prepend" operation. + // Copyright (C) 2021 Network RADIUS SAS. Licenced under CC-by-NC 4.0. // Development of this documentation was sponsored by Network RADIUS SAS. diff --git a/src/lib/util/calc.c b/src/lib/util/calc.c index 276db9e8bd5..6043502c315 100644 --- a/src/lib/util/calc.c +++ b/src/lib/util/calc.c @@ -966,6 +966,18 @@ static int calc_string(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_t cons fr_value_box_bstrndup_shallow(dst, dst->enumv, buf, len, a->tainted | b->tainted); break; + case T_XOR: /* is prepend for strings */ + buf = talloc_array(ctx, char, len + 1); + if (!buf) goto oom; + + len = a->vb_length + b->vb_length; + memcpy(buf, b->vb_strvalue, b->vb_length); + memcpy(buf + b->vb_length, a->vb_strvalue, a->vb_length); + buf[len] = '\0'; + + fr_value_box_bstrndup_shallow(dst, dst->enumv, buf, len, a->tainted | b->tainted); + break; + case T_SUB: /* * The inverse of add! diff --git a/src/tests/keywords/edit-string b/src/tests/keywords/edit-string new file mode 100644 index 00000000000..e93921b6765 --- /dev/null +++ b/src/tests/keywords/edit-string @@ -0,0 +1,27 @@ +# +# PRE: edit +# +&Tmp-String-0 := "foo" +&Tmp-String-0 ^= "bar" + +if (&Tmp-String-0 != "barfoo") { + test_fail +} + +&Tmp-String-0 := "foo" +&Tmp-String-0 += "bar" + +if (&Tmp-String-0 != "foobar") { + test_fail +} + +# +# Subtract is the inverse of add. +# +&Tmp-String-0 -= "bar" + +if (&Tmp-String-0 != "foo") { + test_fail +} + +success