From 3c0e3a1f3530aed0598c33d53bc3faf31bb23702 Mon Sep 17 00:00:00 2001 From: "Alan T. DeKok" Date: Sat, 30 Sep 2023 08:09:18 -0400 Subject: [PATCH] move casting to new syntax. the old syntax will now cause an error --- .../modules/installation/pages/upgrade.adoc | 8 +- src/lib/unlang/xlat_expr.c | 26 +++---- src/tests/keywords/cast-byte | 6 +- src/tests/keywords/cast-integer | 6 +- src/tests/keywords/cast-short | 6 +- src/tests/keywords/escape | 18 ++--- src/tests/keywords/xlat-eval | 2 +- src/tests/keywords/xlat-integer | 4 +- src/tests/unit/condition/base.txt | 73 +++++++++--------- src/tests/unit/condition/casts.txt | 12 +-- src/tests/unit/condition/ip.txt | 2 +- src/tests/unit/xlat/cond_base.txt | 74 ++++++++----------- src/tests/unit/xlat/cond_regex.txt | 2 +- 13 files changed, 119 insertions(+), 120 deletions(-) diff --git a/doc/antora/modules/installation/pages/upgrade.adoc b/doc/antora/modules/installation/pages/upgrade.adoc index da847eb97c..f54008e415 100644 --- a/doc/antora/modules/installation/pages/upgrade.adoc +++ b/doc/antora/modules/installation/pages/upgrade.adoc @@ -696,9 +696,15 @@ Some modules such as rlm_sql_postgresql can have their timeout set via an alternative configuration item (e.g. `radius_db` in the case of postgresql). +== Unlang Syntax + +Many new xref:reference:unlang/index.adoc[unlang] keywords have been added. + +Data type casts have changed from ` ...` to `(ipaddr) ...` + == Xlat expansions -Xlat expansions have been changed from syntax like `%{md5:...}` to `%md5(...)`. +xref:reference:xlat/index.adoc[xlat] expansions have been changed from syntax like `%{md5:...}` to `%md5(...)`. === Removed expansions diff --git a/src/lib/unlang/xlat_expr.c b/src/lib/unlang/xlat_expr.c index 70ffbd6517..f890e92ab1 100644 --- a/src/lib/unlang/xlat_expr.c +++ b/src/lib/unlang/xlat_expr.c @@ -1990,18 +1990,11 @@ static xlat_exp_t *expr_cast_alloc(TALLOC_CTX *ctx, fr_type_t type) static fr_slen_t expr_cast_from_substr(fr_type_t *cast, fr_sbuff_t *in) { - char close = '\0'; fr_sbuff_t our_in = FR_SBUFF(in); fr_sbuff_marker_t m; ssize_t slen; - if (fr_sbuff_next_if_char(&our_in, '<')) { - close = '>'; - - } else if (fr_sbuff_next_if_char(&our_in, '(')) { - close = ')'; - - } else { + if (!fr_sbuff_next_if_char(&our_in, '(')) { no_cast: *cast = FR_TYPE_NULL; return 0; @@ -2009,17 +2002,24 @@ static fr_slen_t expr_cast_from_substr(fr_type_t *cast, fr_sbuff_t *in) fr_sbuff_marker(&m, &our_in); fr_sbuff_out_by_longest_prefix(&slen, cast, fr_type_table, &our_in, FR_TYPE_NULL); - if (fr_type_is_null(*cast)) goto no_cast; + + /* + * We didn't read anything, there's no cast. + */ + if (fr_sbuff_diff(&our_in, &m) == 0) goto no_cast; + + if (!fr_sbuff_next_if_char(&our_in, ')')) goto no_cast; + + if (fr_type_is_null(*cast)) { + fr_strerror_printf("Invalid data type in cast"); + FR_SBUFF_ERROR_RETURN(&m); + } if (!fr_type_is_leaf(*cast)) { fr_strerror_printf("Invalid data type '%s' in cast", fr_type_to_str(*cast)); FR_SBUFF_ERROR_RETURN(&our_in); } - if (!fr_sbuff_next_if_char(&our_in, close)) { - fr_strerror_const("Unterminated cast"); - FR_SBUFF_ERROR_RETURN(&our_in); - } fr_sbuff_adv_past_whitespace(&our_in, SIZE_MAX, NULL); FR_SBUFF_SET_RETURN(in, &our_in); diff --git a/src/tests/keywords/cast-byte b/src/tests/keywords/cast-byte index 119e124ccc..1696c5252a 100644 --- a/src/tests/keywords/cast-byte +++ b/src/tests/keywords/cast-byte @@ -3,14 +3,14 @@ # &Class := 0xad -if (&Class == 173) { +if ((byte)&Class == 173) { success } -if (&Class < 173) { +if ((byte)&Class < 173) { test_fail } -if (&Class > 173) { +if ((byte)&Class > 173) { test_fail } diff --git a/src/tests/keywords/cast-integer b/src/tests/keywords/cast-integer index e3081bcd7e..84459245cb 100644 --- a/src/tests/keywords/cast-integer +++ b/src/tests/keywords/cast-integer @@ -3,14 +3,14 @@ # &Class := 0x00000101 -if (&Class[0] == 257) { +if ((integer)&Class[0] == 257) { success } -if (&Class[0] < 256) { +if ((integer)&Class[0] < 256) { test_fail } -if (&Class[0] > 257) { +if ((integer)&Class[0] > 257) { test_fail } diff --git a/src/tests/keywords/cast-short b/src/tests/keywords/cast-short index f4ff7629aa..4f87e5b8af 100644 --- a/src/tests/keywords/cast-short +++ b/src/tests/keywords/cast-short @@ -3,14 +3,14 @@ # &Class := 0x0101 -if (&Class == 257) { +if ((short)&Class == 257) { success } -if (&Class < 256) { +if ((short)&Class < 256) { test_fail } -if (&Class > 257) { +if ((short)&Class > 257) { test_fail } diff --git a/src/tests/keywords/escape b/src/tests/keywords/escape index 60f6f1ddb1..2b51823842 100644 --- a/src/tests/keywords/escape +++ b/src/tests/keywords/escape @@ -15,39 +15,39 @@ # = not followed by hex and without 2 following chars &Tmp-String-8 := 'a=Az=y' -if (!("%{escape.escape:%{Tmp-String-0}}" == &Tmp-String-0)) { +if (!((string)"%{escape.escape:%{Tmp-String-0}}" == &Tmp-String-0)) { test_fail } -if (!("%{escape.escape:%{Tmp-String-1}}" == &Tmp-String-3)) { +if (!((string)"%{escape.escape:%{Tmp-String-1}}" == &Tmp-String-3)) { test_fail } -if (!("%{escape.escape:%{Tmp-String-2}}" == &Tmp-String-4)) { +if (!((string)"%{escape.escape:%{Tmp-String-2}}" == &Tmp-String-4)) { test_fail } -if (!("%{escape.unescape:%{Tmp-String-0}}" == &Tmp-String-0)) { +if (!((string)"%{escape.unescape:%{Tmp-String-0}}" == &Tmp-String-0)) { test_fail } -if (!("%{escape.unescape:%{Tmp-String-3}}" == "%{Tmp-String-1}")) { +if (!((string)"%{escape.unescape:%{Tmp-String-3}}" == "%{Tmp-String-1}")) { test_fail } -if (!("%{escape.unescape:%{Tmp-String-4}}" == &Tmp-String-2)) { +if (!((string)"%{escape.unescape:%{Tmp-String-4}}" == &Tmp-String-2)) { test_fail } -if (!("%{escape.escape:%{Tmp-String-6}}" == &Tmp-String-7)) { +if (!((string)"%{escape.escape:%{Tmp-String-6}}" == &Tmp-String-7)) { test_fail } -if (!("%{escape.unescape:%{Tmp-String-7}}" == &Tmp-String-6)) { +if (!((string)"%{escape.unescape:%{Tmp-String-7}}" == &Tmp-String-6)) { test_fail } -if (!("%{escape.unescape:%{Tmp-String-8}}" == &Tmp-String-8)) { +if (!((string)"%{escape.unescape:%{Tmp-String-8}}" == &Tmp-String-8)) { test_fail } diff --git a/src/tests/keywords/xlat-eval b/src/tests/keywords/xlat-eval index 9224802dcf..85de15171b 100644 --- a/src/tests/keywords/xlat-eval +++ b/src/tests/keywords/xlat-eval @@ -36,7 +36,7 @@ if (!("%{eval:\%{Tmp-String-1[%{Tmp-Integer-0[2]}]\}}" == 'bar')) { # # Check yielding works # -if ("%(reschedule:)" > 1s) { +if ((time_delta)"%(reschedule:)" > 1s) { test_fail } diff --git a/src/tests/keywords/xlat-integer b/src/tests/keywords/xlat-integer index 57b8a2b8d4..a40990dc60 100644 --- a/src/tests/keywords/xlat-integer +++ b/src/tests/keywords/xlat-integer @@ -38,7 +38,7 @@ if ("%(integer:%{Tmp-String-2})") { # Octets - network order representation of a 4 byte octet string &Tmp-Integer-1 := "%(integer:%{Tmp-Octets-0})" -if (!(%{Tmp-Octets-0} == %{Tmp-Integer-1})) { +if (!(%{Tmp-Octets-0} == (octets)%{Tmp-Integer-1})) { test_fail } @@ -49,7 +49,7 @@ if (!(&Tmp-Integer-1 == 959985457)) { # Octets - network order representation of a 8 byte octet string &Tmp-uint64-0 := "%(integer:%{Tmp-Octets-1})" -if (!(%{Tmp-Octets-1} == %{Tmp-uint64-0})) { +if (!(%{Tmp-Octets-1} == (octets)%{Tmp-uint64-0})) { test_fail } diff --git a/src/tests/unit/condition/base.txt b/src/tests/unit/condition/base.txt index 78fbb08637..13d657fbe3 100644 --- a/src/tests/unit/condition/base.txt +++ b/src/tests/unit/condition/base.txt @@ -140,26 +140,31 @@ match (&User-Name != &User-Password) condition !(&User-Name != &User-Password) match !(&User-Name != &User-Password) -condition ::1 +condition (ipv6addr)::1 match ::1 -condition &Filter-Id == &Framed-IP-Address +condition (ipaddr)&Filter-Id == &Framed-IP-Address match ((ipaddr)&Filter-Id == &Framed-IP-Address) # # We can automatically promote things as needed. But if the # user forces incompatible types, then that's an error. # -condition &Filter-Id == &Framed-IP-Address -match ERROR offset 23: No operand found. Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value +# @todo - cast - this seems rather a bit wrong +# +condition (ipaddr)&Filter-Id == (uint) &Framed-IP-Address +match (((ipaddr)&Filter-Id == uint) & Framed-IP-Address) -condition &Filter-Id == "foo" -match ERROR offset 1: No operand found. Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value +# +# @todo - cast - yeah, this is quite wrong. +# +condition (blerg)&Filter-Id == "foo" +match (blerg & (Filter-Id == "foo")) # # Normalize things # -condition 127.0.0.1 < &Framed-IP-Address +condition (ipaddr)127.0.0.1 < &Framed-IP-Address match (127.0.0.1 < &Framed-IP-Address) # =* and !* are only for attrs / lists @@ -183,10 +188,10 @@ condition !&User-Name !* bar match ERROR offset 13: Invalid operator # redundant casts get squashed -condition &Framed-IP-Address == 127.0.0.1 +condition (ipaddr)&Framed-IP-Address == 127.0.0.1 match (&Framed-IP-Address == 127.0.0.1) -condition &Framed-IP-Address <= 192.168.0.0/16 +condition (cidr)&Framed-IP-Address <= 192.168.0.0/16 match ((ipv4prefix)&Framed-IP-Address <= 192.168.0.0/16) # All IP address literals should be parsed as prefixes @@ -229,7 +234,7 @@ condition &Event-Timestamp == 'January 1, 2012' #data &Event-Timestamp == 'Jan 1 2012 00:00:00 EST' # literals are parsed when the conditions are parsed -condition X == 1 +condition (integer)X == 1 match ERROR offset 10: Failed parsing string as type 'uint32' # @@ -242,28 +247,28 @@ match (&NAS-Port == X) # The RHS is a static string, so this gets mashed to a literal, # and then statically evaluated. # -condition 127.0.0.1 == "127.0.0.1" +condition (ipaddr)127.0.0.1 == "127.0.0.1" match true -condition 127.0.0.1 == "%{md4: 127.0.0.1}" +condition (ipaddr)127.0.0.1 == "%{md4: 127.0.0.1}" match (127.0.0.1 == %(cast:string "%{md4: 127.0.0.1}")) # # Bare %{...} is allowed. # -condition 127.0.0.1 == %{md4:127.0.0.1} +condition (ipaddr)127.0.0.1 == %{md4:127.0.0.1} match (127.0.0.1 == %{md4:127.0.0.1}) -condition 127.0.0.1 == %{md4: SELECT user FROM table WHERE user='%{User-Name}'} +condition (ipaddr)127.0.0.1 == %{md4: SELECT user FROM table WHERE user='%{User-Name}'} match (127.0.0.1 == %{md4: SELECT user FROM table WHERE user='%{User-Name}'}) -condition 00:11:22:33:44:55 == "00:11:22:33:44:55" +condition (ether) 00:11:22:33:44:55 == "00:11:22:33:44:55" match true -condition 00:11:22:33:44:55 == "%{md4:00:11:22:33:44:55}" +condition (ether) 00:11:22:33:44:55 == "%{md4:00:11:22:33:44:55}" match (00:11:22:33:44:55 == %(cast:string "%{md4:00:11:22:33:44:55}")) -condition 00:XX:22:33:44:55 == 00:11:22:33:44:55 +condition (ether) 00:XX:22:33:44:55 == 00:11:22:33:44:55 match ERROR offset 12: Missing separator, expected ':' # @@ -296,7 +301,7 @@ match true # # Both sides static data with a cast: evaluate at parse time. # -condition 20 < 100 +condition (integer)20 < 100 match true # @@ -337,17 +342,17 @@ match (&User-Name == "bob") condition (&User-Name == "%{md4: blah}") match (&User-Name == %(cast:string "%{md4: blah}")) -condition 127.0.0.1 == 2130706433 +condition (ipaddr)127.0.0.1 == 2130706433 match true # /32 suffix should be trimmed for this type -condition 127.0.0.1/32 == 127.0.0.1 +condition (ipaddr)127.0.0.1/32 == 127.0.0.1 match true -condition 127.0.0.1/327 == 127.0.0.1 +condition (ipaddr)127.0.0.1/327 == 127.0.0.1 match ERROR offset 9: Invalid IPv4 mask length "/327". Should be between 0-32 -condition 127.0.0.1/32 == 127.0.0.1 +condition (ipaddr)127.0.0.1/32 == 127.0.0.1 match true condition (/foo/) @@ -410,7 +415,7 @@ match &User-Name # # Forbidden data types in cast # -condition ("foo" == &User-Name) +condition ((vsa)"foo" == &User-Name) match ERROR offset 2: Invalid data type 'vsa' in cast # @@ -418,11 +423,11 @@ match ERROR offset 2: Invalid data type 'vsa' in cast # of the same type, then re-write it so that the attribute # is on the LHS of the condition. # -condition "foo" == &User-Name +condition (string)"foo" == &User-Name match ("foo" == &User-Name) # This used to be expr, but expr isn't a builtin, so it failed... -condition "%{md4: 1 + 1}" < &NAS-Port +condition (integer)"%{md4: 1 + 1}" < &NAS-Port match (%(cast:uint32 "%{md4: 1 + 1}") < &NAS-Port) # @@ -432,7 +437,7 @@ match (%(cast:uint32 "%{md4: 1 + 1}") < &NAS-Port) condition &Filter-Id == &Framed-IP-Address match (&Filter-Id == &Framed-IP-Address) -condition 127.0.0.1 == &Filter-Id +condition (ipaddr)127.0.0.1 == &Filter-Id match (127.0.0.1 == &Filter-Id) condition &Tmp-uint64-0 == &request.Foo-Stuff-Bar @@ -444,7 +449,7 @@ match (&Tmp-uint64-0 == &reply.Foo-Stuff-Bar) # # Casting attributes of different size # -condition &Tmp-uint64-0 == &Framed-IP-Address +condition (ipaddr)&Tmp-uint64-0 == &Framed-IP-Address match ERROR offset 9: Cannot cast type 'uint64' to 'ipaddr' # @@ -452,17 +457,17 @@ match ERROR offset 9: Cannot cast type 'uint64' to 'ipaddr' # if the prefix is /32. We don't know enough at compile time, # so this may be a run-time failure. # -condition &PMIP6-Home-IPv4-HoA == &Framed-IP-Address +condition (ipaddr)&PMIP6-Home-IPv4-HoA == &Framed-IP-Address match ((ipaddr)&PMIP6-Home-IPv4-HoA == &Framed-IP-Address) # but these are allowed -condition &Tmp-uint64-0 == "%{module: foo}" +condition (ether)&Tmp-uint64-0 == "%{module: foo}" match ((ether)&Tmp-uint64-0 == %(cast:string "%{module: foo}")) -condition &Filter-Id == &Framed-IP-Address +condition (ipaddr)&Filter-Id == &Framed-IP-Address match ((ipaddr)&Filter-Id == &Framed-IP-Address) -condition &Class == &Framed-IP-Address +condition (ipaddr)&Class == &Framed-IP-Address match ((ipaddr)&Class == &Framed-IP-Address) # @@ -614,10 +619,10 @@ match (&User-Name != "foo\nbar") condition 192.168.0.0/16 > 192.168.1.2 match true -condition 192.168.0.0/16 > 192.168.1.2 +condition (ipv4prefix)192.168.0.0/16 > 192.168.1.2 match true -condition &NAS-IP-Address == 192.168.0.0/24 +condition (ipv4prefix)&NAS-IP-Address == 192.168.0.0/24 match ((ipv4prefix)&NAS-IP-Address == 192.168.0.0/24) # @@ -625,7 +630,7 @@ match ((ipv4prefix)&NAS-IP-Address == 192.168.0.0/24) # and, move the cast to the attribute, as the RHS # is parsed as ipv4prefix # -condition 192.168.0.0/24 > &NAS-IP-Address +condition (ipv4prefix)192.168.0.0/24 > &NAS-IP-Address match (192.168.0.0/24 > &NAS-IP-Address) # diff --git a/src/tests/unit/condition/casts.txt b/src/tests/unit/condition/casts.txt index 4bebebd903..d39d811931 100644 --- a/src/tests/unit/condition/casts.txt +++ b/src/tests/unit/condition/casts.txt @@ -8,28 +8,28 @@ proto-dictionary radius tmpl-rules allow_unresolved=yes allow_unknown=yes # Forcefully cast RHS bareword -condition &User-Name == 192.168.0.1 +condition &User-Name == (ipaddr)192.168.0.1 match (&User-Name == 192.168.0.1) # Forcefully cast LHS bareword -condition 192.168.0.1 == &User-Name +condition (ipaddr)192.168.0.1 == &User-Name match (192.168.0.1 == &User-Name) # Forcefully cast RHS single quotes # we can cast the data during parsing, so we do that. -condition &Framed-IP-Address == '192.168.0.1' +condition &Framed-IP-Address == (ipaddr)'192.168.0.1' match (&Framed-IP-Address == 192.168.0.1) # Forcefully cast LHS single quotes -condition '192.168.0.1' == &Framed-IP-Address +condition (ipaddr)'192.168.0.1' == &Framed-IP-Address match (192.168.0.1 == &Framed-IP-Address) # Forcefully cast RHS double quotes -condition &User-Name == "192.168.0.1" +condition &User-Name == (ipaddr)"192.168.0.1" match (&User-Name == 192.168.0.1) # Forcefully cast LHS single quotes -condition "192.168.0.1" == &User-Name +condition (ipaddr)"192.168.0.1" == &User-Name match (192.168.0.1 == &User-Name) count diff --git a/src/tests/unit/condition/ip.txt b/src/tests/unit/condition/ip.txt index 7c82417e5b..e78c093fab 100644 --- a/src/tests/unit/condition/ip.txt +++ b/src/tests/unit/condition/ip.txt @@ -10,7 +10,7 @@ proto-dictionary radius condition &NAS-IPv6-Address == :: match (&NAS-IPv6-Address == ::) -condition &NAS-IP-Address == * +condition &NAS-IP-Address == (ipaddr)* match (&NAS-IP-Address == 0.0.0.0) condition &NAS-IP-Address == 0.0.0.0 diff --git a/src/tests/unit/xlat/cond_base.txt b/src/tests/unit/xlat/cond_base.txt index 6162d0a560..3601a39ee6 100644 --- a/src/tests/unit/xlat/cond_base.txt +++ b/src/tests/unit/xlat/cond_base.txt @@ -163,7 +163,7 @@ match ERROR offset 1: Operator '!' is only applied to the left hand side of the # # We allow a cast for the existence check. Why not? # -xlat_purify ::1 +xlat_purify (ipv6addr)::1 match ::1 # new casts are allowed, too. @@ -176,32 +176,20 @@ match ERROR offset 11: Failed to parse IPv6 address string "xxx" # # Various casts # -xlat_purify &Filter-Id == &Framed-IP-Address +xlat_purify (ipaddr)&Filter-Id == &Framed-IP-Address match ((ipaddr)&Filter-Id == &Framed-IP-Address) -# -# We can automatically promote things as needed. But if the -# user forces incompatible types, then that's an error. -# -# @todo - parsing - better errors for casts -# -xlat_purify &Filter-Id == &Framed-IP-Address -match ERROR offset 23: No operand found. Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value - -xlat_purify &Filter-Id == "foo" -match ERROR offset 1: No operand found. Expected &ref, literal, 'quoted literal', "%{expansion}", or enum value - # # Don't normalize things # -xlat_purify 127.0.0.1 < &Framed-IP-Address +xlat_purify (ipaddr)127.0.0.1 < &Framed-IP-Address match (127.0.0.1 < &Framed-IP-Address) # redundant casts get squashed -xlat_purify &Framed-IP-Address == 127.0.0.1 +xlat_purify (ipaddr)&Framed-IP-Address == 127.0.0.1 match (&Framed-IP-Address == 127.0.0.1) -xlat_purify &Framed-IP-Address <= 192.168.0.0/16 +xlat_purify (cidr)&Framed-IP-Address <= 192.168.0.0/16 match ((ipv4prefix)&Framed-IP-Address <= 192.168.0.0/16) # All IP address literals should be parsed as prefixes @@ -244,7 +232,7 @@ xlat_purify &Event-Timestamp == 'January 1 2012' #match (&Event-Timestamp == 'Jan 1 2012 00:00:00 EST') # literals are parsed when the conditions are parsed -xlat_purify X == 1 +xlat_purify (integer)X == 1 match ERROR offset 10: Failed parsing string as type 'uint32' # @@ -259,12 +247,12 @@ match ERROR offset 1: Failed parsing string as type 'uint32' # The RHS is a static string, so this gets mashed to a literal, # and then statically evaluated. # -xlat_purify 127.0.0.1 == "127.0.0.1" +xlat_purify (ipaddr)127.0.0.1 == "127.0.0.1" match true # LHS is IPaddr, RHS is string (malformed IP address). # Condition code attempts to cast md4 hash to IP address resulting in an invalid comparison -xlat_purify 127.0.0.1 == "%{md4: 127.0.0.1}" +xlat_purify (ipaddr)127.0.0.1 == "%{md4: 127.0.0.1}" match NULL # @@ -272,20 +260,20 @@ match NULL # # Invalid cast from octets to ipaddr. -xlat_purify 127.0.0.1 == %{md4:127.0.0.1} +xlat_purify (ipaddr)127.0.0.1 == %{md4:127.0.0.1} match NULL -xlat_purify 127.0.0.1 == %{md4: SELECT user FROM table WHERE user='%{User-Name}'} +xlat_purify (ipaddr)127.0.0.1 == %{md4: SELECT user FROM table WHERE user='%{User-Name}'} match (127.0.0.1 == %{md4: SELECT user FROM table WHERE user='%{User-Name}'}) -xlat_purify 00:11:22:33:44:55 == "00:11:22:33:44:55" +xlat_purify (ether) 00:11:22:33:44:55 == "00:11:22:33:44:55" match true # Invalid cast from octets to ether. -xlat_purify 00:11:22:33:44:55 == "%{md4:00:11:22:33:44:55}" +xlat_purify (ether)00:11:22:33:44:55 == "%{md4:00:11:22:33:44:55}" match NULL -xlat_purify 00:XX:22:33:44:55 == 00:11:22:33:44:55 +xlat_purify (ether) 00:XX:22:33:44:55 == 00:11:22:33:44:55 match ERROR offset 12: Missing separator, expected ':' # @@ -308,7 +296,7 @@ match 0 # # Both sides static data with a cast: evaluate at parse time. # -xlat_purify 20 < 100 +xlat_purify (integer)20 < 100 match true # @@ -356,17 +344,17 @@ match (&User-Name == 0x544924d05ec4481925ba3749a096a0a7) xlat_purify (&User-Name == %{md4: blah}) match (&User-Name == 0x544924d05ec4481925ba3749a096a0a7) -xlat_purify 127.0.0.1 == 2130706433 +xlat_purify (ipaddr)127.0.0.1 == 2130706433 match true # /32 suffix should be trimmed for this type -xlat_purify 127.0.0.1/32 == 127.0.0.1 +xlat_purify (ipaddr)127.0.0.1/32 == 127.0.0.1 match true -xlat_purify 127.0.0.1/327 == 127.0.0.1 +xlat_purify (ipaddr)127.0.0.1/327 == 127.0.0.1 match ERROR offset 9: Invalid IPv4 mask length "/327". Should be between 0-32 -xlat_purify 127.0.0.1/32 == 127.0.0.1 +xlat_purify (ipaddr)127.0.0.1/32 == 127.0.0.1 match true xlat_purify (/foo/) @@ -429,7 +417,7 @@ match &User-Name # # Forbidden data types in cast # -xlat_purify ("foo" == &User-Name) +xlat_purify ((vsa)"foo" == &User-Name) match ERROR offset 2: Invalid data type 'vsa' in cast # @@ -437,7 +425,7 @@ match ERROR offset 2: Invalid data type 'vsa' in cast # of the same type, then re-write it so that the attribute # is on the LHS of the condition. # -xlat_purify "foo" == &User-Name +xlat_purify (string)"foo" == &User-Name match ("foo" == &User-Name) # This used to be expr, but expr isn't a builtin, so it failed... @@ -447,7 +435,7 @@ match ("foo" == &User-Name) # # ERROR: Failed casting 0x002ade8665c69219ca16bd108d92c8d5 to data type uint32: Invalid cast from octets to uint32. Source length 16 is greater than destination type size 4 # -xlat_purify "%{md4: 1 + 1}" < &NAS-Port +xlat_purify (integer)"%{md4: 1 + 1}" < &NAS-Port match (%(cast:uint32 "%{md4: 1 + 1}") < &NAS-Port) # @@ -456,7 +444,7 @@ match (%(cast:uint32 "%{md4: 1 + 1}") < &NAS-Port) xlat_purify &Filter-Id == &Framed-IP-Address match (&Filter-Id == &Framed-IP-Address) -xlat_purify 127.0.0.1 == &Filter-Id +xlat_purify (ipaddr)127.0.0.1 == &Filter-Id match (127.0.0.1 == &Filter-Id) xlat_purify &Tmp-uint64-0 == &request.Tmp-String-0 @@ -468,7 +456,7 @@ match (&Tmp-uint64-0 == &reply.Tmp-String-0) # # Casting attributes of different size # -xlat_purify &Tmp-uint64-0 == &Framed-IP-Address +xlat_purify (ipaddr)&Tmp-uint64-0 == &Framed-IP-Address match ERROR offset 9: Cannot cast type 'uint64' to 'ipaddr' # @@ -476,17 +464,17 @@ match ERROR offset 9: Cannot cast type 'uint64' to 'ipaddr' # if the prefix is /32. We don't know enough at compile time, # so this may be a run-time failure. # -xlat_purify &PMIP6-Home-IPv4-HoA == &Framed-IP-Address +xlat_purify (ipaddr)&PMIP6-Home-IPv4-HoA == &Framed-IP-Address match ((ipaddr)&PMIP6-Home-IPv4-HoA == &Framed-IP-Address) # but these are allowed -xlat_purify &Tmp-uint64-0 == "%{module: foo}" +xlat_purify (ether)&Tmp-uint64-0 == "%{module: foo}" match ((ether)&Tmp-uint64-0 == %(cast:string "%{module: foo}")) -xlat_purify &Filter-Id == &Framed-IP-Address +xlat_purify (ipaddr)&Filter-Id == &Framed-IP-Address match ((ipaddr)&Filter-Id == &Framed-IP-Address) -xlat_purify &Class == &Framed-IP-Address +xlat_purify (ipaddr)&Class == &Framed-IP-Address match ((ipaddr)&Class == &Framed-IP-Address) # @@ -614,10 +602,10 @@ xlat_purify 192.168.0.0/16 > 192.168.1.2 match true -xlat_purify 192.168.0.0/16 > 192.168.1.2 +xlat_purify (ipv4prefix)192.168.0.0/16 > 192.168.1.2 match true -xlat_purify &NAS-IP-Address == 192.168.0.0/24 +xlat_purify (ipv4prefix)&NAS-IP-Address == 192.168.0.0/24 match ((ipv4prefix)&NAS-IP-Address == 192.168.0.0/24) # @@ -625,7 +613,7 @@ match ((ipv4prefix)&NAS-IP-Address == 192.168.0.0/24) # and, move the cast to the attribute, as the RHS # is parsed as ipv4prefix # -xlat_purify 192.168.0.0/24 > &NAS-IP-Address +xlat_purify (ipv4prefix)192.168.0.0/24 > &NAS-IP-Address match (192.168.0.0/24 > &NAS-IP-Address) # @@ -779,4 +767,4 @@ xlat_purify (192.168.0.1 !== 192.168.0.2) match true count -match 332 +match 328 diff --git a/src/tests/unit/xlat/cond_regex.txt b/src/tests/unit/xlat/cond_regex.txt index 376ccc47f2..03d08dee8d 100644 --- a/src/tests/unit/xlat/cond_regex.txt +++ b/src/tests/unit/xlat/cond_regex.txt @@ -60,7 +60,7 @@ match (&Tmp-Integer-0 =~ /%{Tmp-Integer-1} foo/) # If they're dumb enough to add a cast, then it will be just cast again # to "string" before the regular expression is evaluated. # -xlat_purify &Tmp-String-0 =~ /foo/ +xlat_purify (integer)&Tmp-String-0 =~ /foo/ match ((uint32)&Tmp-String-0 =~ /foo/) xlat_purify &Tmp-String-0 =~ /foo/ -- 2.47.3