]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
allow for failed xlats to return empty strings, as a special case
authorAlan T. DeKok <aland@freeradius.org>
Tue, 22 Nov 2022 21:11:18 +0000 (16:11 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 22 Nov 2022 21:32:14 +0000 (16:32 -0500)
&foo := "%{failed xlat}"

will return

&foo == ""

But

&foo := %{failed xlat}

without quotes, will not create &foo.

14 files changed:
src/lib/unlang/edit.c
src/tests/keywords/date
src/tests/keywords/mschap
src/tests/keywords/rand
src/tests/keywords/randstr
src/tests/keywords/subrequest-request-qualifiers
src/tests/keywords/tolower
src/tests/keywords/toupper
src/tests/keywords/unpack
src/tests/keywords/urlquote
src/tests/keywords/xlat-alternation
src/tests/modules/client/xlat.unlang
src/tests/modules/exec/async.unlang
src/tests/modules/exec/sync.unlang

index 0dee31bd1e2f880d8d34ce6a3a07ccc79a4970ba..b56f0303228a32ad98c7c0979daf4b9eddb302c0 100644 (file)
@@ -484,15 +484,18 @@ static int apply_edits_to_leaf(request_t *request, unlang_frame_state_edit_t *st
                        /*
                         *      The caller asked for a string, so instead of returning a list, return a string.
                         *
-                        *      @todo - this should arguably be the responsibility of xlat_push(), or
-                        *      tmpl_push().  If the input xlat/tmpl is quoted, then the output should be a
-                        *      single value-box which is the final string.
+                        *      If there's no output, then it's an empty string.
+                        *
+                        *      We have to check this here, because the quote is part of the tmpl, and we call
+                        *      xlat_push(), which doesn't know about the quote.
                         */
                        box = fr_value_box_list_head(&current->rhs.result);
 
-                       if (!box) goto no_rhs;
+                       if (!box) {
+                               MEM(box = fr_value_box_alloc(state, FR_TYPE_STRING, NULL, false));
+                               fr_value_box_list_insert_tail(&current->rhs.result, box);
 
-                       if (fr_value_box_list_concat_in_place(box, box, &current->rhs.result, FR_TYPE_STRING,
+                       } else if (fr_value_box_list_concat_in_place(box, box, &current->rhs.result, FR_TYPE_STRING,
                                                              FR_VALUE_BOX_LIST_FREE_BOX, true, 8192) < 0) {
                                RWDEBUG("Failed converting result to string");
                                return -1;
@@ -533,7 +536,6 @@ static int apply_edits_to_leaf(request_t *request, unlang_frame_state_edit_t *st
        }
 
        if (!box) {
-       no_rhs:
                RWDEBUG("%s %s ... - Assignment failed to having no value on right-hand side", map->lhs->name, fr_tokens[map->op]);
                return -1;
        }
index 9a54108c4163da42cb53f7d5104787a48aa31cd1..a5e4f76c831da8dec418a51870c1bfb686512494 100644 (file)
@@ -47,7 +47,7 @@ if (&Tmp-String-2 != '2022-08-08 19:04:19') {
 
 # Invalid format
 &Tmp-String-3 := '201-32-22 17:25:00'
-&Tmp-String-4 := "%(sqldate:%{Tmp-String-3})"
+&Tmp-String-4 := %(sqldate:%{Tmp-String-3})
 
 # This shouldn't exist, as the RHS above is NULL, and therefore the assignment will fail
 if (&Tmp-String-4) {
index b3fceb6f689bf9c2420086db09b3ec2433151e60..e7879066a1d76c810c24f0224d46f7f812a4243e 100644 (file)
@@ -2,33 +2,37 @@
 #  PRE: if
 #
 
+#
+#  over-write the existing User-Name
+#
+&User-Name := 'EXAMPLE\bob'
+
 # MS CHAPv1
 &request += {
-       &User-Name = 'EXAMPLE\bob'
        &Vendor-Specific.Microsoft.CHAP-Challenge = 0xe96e4fff2955c4f1
        &Vendor-Specific.Microsoft.CHAP-Response = 0x00010000000000000000000000000000000000000000000000008860bbaac0cd3960b4ce5dc6f0f7a462b897ef530484e80f
 }
 
 &request += {
-       &Tmp-Octets-0 = "%(mschap:Challenge)"
-       &Tmp-Octets-1 = "%(mschap:NT-Response)"
+       &Tmp-Octets-0 = %(mschap:Challenge)
+       &Tmp-Octets-1 = %(mschap:NT-Response)
        &Tmp-String-0 = "%(mschap:NT-Domain)"
        &Tmp-String-1 = "%(mschap:User-Name)"
 }
 
-if (&Tmp-Octets-0 != 0xe96e4fff2955c4f1) {
+if !(&Tmp-Octets-0 == 0xe96e4fff2955c4f1) {
        test_fail
 }
 
-if (&Tmp-Octets-1 != 0x8860bbaac0cd3960b4ce5dc6f0f7a462b897ef530484e80f) {
+if !(&Tmp-Octets-1 == 0x8860bbaac0cd3960b4ce5dc6f0f7a462b897ef530484e80f) {
        test_fail
 }
 
-if (&Tmp-String-0 != 'EXAMPLE') {
+if !(&Tmp-String-0 == 'EXAMPLE') {
        test_fail
 }
 
-if (&Tmp-String-1 != 'bob') {
+if !(&Tmp-String-1 == 'bob') {
        test_fail
 }
 
@@ -36,19 +40,19 @@ if (&Tmp-String-1 != 'bob') {
 
 &Tmp-Octets-0 := "%(mschap:LM-Response)"
 
-if (&Tmp-Octets-0 != 0x6937d7935bb28a4c1dafe6a193bdea7a853a74d8bcf6db15) {
+if !(&Tmp-Octets-0 == 0x6937d7935bb28a4c1dafe6a193bdea7a853a74d8bcf6db15) {
        test_fail
 }
 
 # Hashing
-&Tmp-Octets-0 := "%(mschap:NT-Hash testing_123)"
-&Tmp-Octets-1 := "%(mschap:LM-Hash testing_123)"
+&Tmp-Octets-0 := %(mschap:NT-Hash testing_123)
+&Tmp-Octets-1 := %(mschap:LM-Hash testing_123)
 
-if (&Tmp-Octets-0 != 0xfa782604f85eb3564f555648341b53e4) {
+if !(&Tmp-Octets-0 == 0xfa782604f85eb3564f555648341b53e4) {
        test_fail
 }
 
-if (&Tmp-Octets-1 != 0x2d5545077d7b7d2ae4343f96ab15c596) {
+if !(&Tmp-Octets-1 == 0x2d5545077d7b7d2ae4343f96ab15c596) {
        test_fail
 }
 
@@ -58,14 +62,14 @@ if (&Tmp-Octets-1 != 0x2d5545077d7b7d2ae4343f96ab15c596) {
 &Vendor-Specific.Microsoft.CHAP-Challenge := 0x04408dc2a98dae1ce351dfc53f57d08e
 &Vendor-Specific.Microsoft.CHAP2-Response := 0x00010e93cfbfcef8d5b6af42d2b2ca5b43180000000000000000bc068d1e8c54de5e9db78e6736d686eb88a999dd7fa239b200
 
-&Tmp-Octets-0 := "%(mschap:Challenge)"
-&Tmp-Octets-1 := "%(mschap:NT-Response)"
+&Tmp-Octets-0 := %(mschap:Challenge)
+&Tmp-Octets-1 := %(mschap:NT-Response)
 
-if (&Tmp-Octets-0 != 0xad18b6b8e1478b4c) {
+if !(&Tmp-Octets-0 == 0xad18b6b8e1478b4c) {
        test_fail
 }
 
-if (&Tmp-Octets-1 != 0xbc068d1e8c54de5e9db78e6736d686eb88a999dd7fa239b2) {
+if !(&Tmp-Octets-1 == 0xbc068d1e8c54de5e9db78e6736d686eb88a999dd7fa239b2) {
        test_fail
 }
 
@@ -73,7 +77,7 @@ if (&Tmp-Octets-1 != 0xbc068d1e8c54de5e9db78e6736d686eb88a999dd7fa239b2) {
 &Vendor-Specific.Microsoft.CHAP-Challenge := 0xf0eac4151d5346662ba8c5e428
 &Tmp-String-0 := "%(mschap:Challenge)"
 
-if (&Tmp-String-0 != "") {
+if !(&Tmp-String-0 == "") {
        test_fail
 }
 
index ef3070c2fafbb7e2acb53ad650f0322309569c0f..760d3b385bad5e62d3d0a7657b16a909bfc4ac4c 100644 (file)
@@ -3,7 +3,7 @@
 #
 #  Negative limit should have failed assignment
 #
-if (&Tmp-String-0) {
+if !(&Tmp-String-0 == "") {
        test_fail
 }
 
@@ -12,11 +12,15 @@ if (&Tmp-String-0) {
 #
 #  Invalid limit should have failed assignment
 #
-if (&Tmp-String-0) {
+if !(&Tmp-String-0 == "") {
        test_fail
 }
 
-&Tmp-Integer-0 := "%{rand:123}"
+&Tmp-Integer-0 := %{rand:123}
+
+if (!&Tmp-Integer-0) {
+       test_fail
+}
 
 #
 #  Make sure random number is within limit
index fe75538c886e4be58bdedb2d81de3b5bcc7c1e2a..24b50ac0a61af315160eac1e0e59f9cfc556d4e2 100644 (file)
@@ -6,48 +6,48 @@
 }
 
 #
-#  These next two assignments fail, so they can't go
-#  into the above list.  If they were there, then the
-#  entire list assignment would fail.
+#  This next assignment fails, so it can't go into the above list.  If
+#  it was there, then the entire list assignment would fail.
 #
 &Tmp-String-0 := "%{randstr:%{Tmp-String-0}}"
-&Tmp-String-4 := "%{randstr:G}"
 
 #
 #  Empty output on empty input
 #
-if (&Tmp-String-0 != "") {
+if !(&Tmp-String-0 == "") {
        test_fail
 }
 
 #
 #  Check length of output
 #
-if ("%{strlen:%{Tmp-String-1}}" != 3) {
+if (%{strlen:%{Tmp-String-1}} != 3) {
        test_fail
 }
 
-if ("%{strlen:%{Tmp-String-2}}" != 24) {
+if (%{strlen:%{Tmp-String-2}} != 24) {
        test_fail
 }
 #
 #  Check maximum repetition
 #
-if ("%{strlen:%{Tmp-String-3}}" != 1025) {
+if (%{strlen:%{Tmp-String-3}} != 1025) {
        test_fail
 }
 
 #
 #  Check invalid character class
 #
-if (&Tmp-String-4) {
+&Tmp-String-4 := "%{randstr:G}"
+
+if !(&Tmp-String-4 == "") {
        test_fail
 }
 
 #
 #  Check repetition of binary output
 #
-if ("%(length:%{Tmp-String-5})" != 10) {
+if (%(length:%{Tmp-String-5}) != 10) {
        test_fail
 }
 
index f34d18c02d4ff9a1fc9d5658cb3c4d766e833c37..6c38de1e4b515826cda5e0687d6a23840a317fab 100644 (file)
@@ -20,54 +20,50 @@ subrequest Access-Request {
                                &Tmp-String-4 = &outer.User-Name
                                &Tmp-String-5 = &current.outer.User-Name
                                &Tmp-String-6 = &parent.current.outer.User-Name
+                               &Tmp-String-7 = "%{parent.parent.parent.parent.User-Name}"
+                               &Tmp-String-8 = "%{outer.parent.User-Name}"
                        }
-
-                       #
-                       #  These fail, so they belong on their own.
-                       #
-                       &outer.request.Tmp-String-7 := "%{parent.parent.parent.parent.User-Name}"
-                       &outer.request.Tmp-String-8 := "%{outer.parent.User-Name}"
                }
        }
 }
 
-if (&Outer-Realm-Name != 'testing123') {
+if !(&Outer-Realm-Name == 'testing123') {
        test_fail
 }
 
-if (&Tmp-String-0 != 'joe') {
+if !(&Tmp-String-0 == 'joe') {
        test_fail
 }
 
-if (&Tmp-String-1 != 'jim') {
+if !(&Tmp-String-1 == 'jim') {
        test_fail
 }
 
-if (&tmp-String-2 != 'obo') {
+if !(&Tmp-String-2 == 'obo') {
        test_fail
 }
 
-if (&Tmp-String-3 != 'bob') {
+if !(&Tmp-String-3 == 'bob') {
        test_fail
 }
 
-if (&Tmp-String-4 != 'bob') {
+if !(&Tmp-String-4 == 'bob') {
        test_fail
 }
 
-if (&Tmp-String-5 != 'bob') {
+if !(&Tmp-String-5 == 'bob') {
        test_fail
 }
 
-if (&Tmp-String-6 != 'bob') {
+if !(&Tmp-String-6 == 'bob') {
        test_fail
 }
 
-if (&Tmp-String-7) {
+if !(&Tmp-String-7 == "") {
        test_fail
 }
 
-if (&Tmp-String-8) {
+if !(&Tmp-String-8 == "") {
        test_fail
 }
 
index b1a2b6b629bee34af68b879e9955d19e0f0f0894..5283ea4904138c0383352affa776f01444536df6 100644 (file)
@@ -2,9 +2,7 @@
 # PRE: if
 #
 &Tmp-String-0  := "AbCdE"
-
 &Tmp-String-0  := "%{tolower:%{Tmp-String-0}}"
-
 &Tmp-String-1  := "%{tolower:AAbbCCdd}"
 
 #
@@ -21,7 +19,7 @@ if (&Tmp-String-1 != "aabbccdd") {
        test_fail
 }
 
-if (&Tmp-String-2) {
+if !(&Tmp-String-2 == "") {
        test_fail
 }
 
index efa943935714a0fced7e2931076680b9ee08a8b8..e08425dbed30ac37f7152d87c6a410ee29e46884 100644 (file)
@@ -15,7 +15,7 @@ if (&Tmp-String-1 != "AABBCCDD") {
        test_fail
 }
 
-if (&Tmp-String-2) {
+if !(&Tmp-String-2 == "") {
        test_fail
 }
 
index ce04e6b6bf835cd1074066a48cd9f189b58bcb33..a8dc488f5630cfc2738c4040d12e140f65ad57a7 100644 (file)
@@ -7,11 +7,11 @@
 &Tmp-String-0 := "%(unpack:%{Tmp-Octets-0} 0 ipaddr)"
 &Tmp-IP-Address-0 := "%(unpack:%{Tmp-Octets-0} 0 ipaddr)"
 
-if (&Tmp-String-0 != "127.0.0.1") {
+if !(&Tmp-String-0 == "127.0.0.1") {
        test_fail
 }
 
-if (&Tmp-IP-Address-0 != 127.0.0.1) {
+if !(&Tmp-IP-Address-0 == 127.0.0.1) {
        test_fail
 }
 
@@ -19,20 +19,20 @@ if (&Tmp-IP-Address-0 != 127.0.0.1) {
 &Tmp-Integer-0 := "%(unpack:%{Tmp-Octets-0} 4 uint16)"
 
 # Octets 4 and 5 == 0x0304 == 772
-if (&Tmp-Integer-0 != 772) {
+if ~(&Tmp-Integer-0 == 772) {
        test_fail
 }
 
 # truncation
 &Tmp-String-0 := "0x0011223344556677"
 &Tmp-String-1 := "%(unpack:%{Tmp-String-0} 0 ether)"
-if (&Tmp-String-1 != "00:11:22:33:44:55") {
+if !(&Tmp-String-1 == "00:11:22:33:44:55") {
        test_fail
 }
 
 &Tmp-String-0 := "0x48656C6C6F"
 &Tmp-String-1 := "%(unpack:%{Tmp-String-0} 0 string)"
-if (&Tmp-String-1 != "Hello") {
+if !(&Tmp-String-1 == "Hello") {
        test_fail
 }
 
@@ -40,7 +40,7 @@ if (&Tmp-String-1 != "Hello") {
 &request -= &Tmp-String-1[*]
 &Tmp-String-1 := "%(unpack:%{Tmp-String-0} 10 string)"
 
-if (&Tmp-String-1) {
+if !(&Tmp-String-1 == "") {
        test_fail
 }
 
@@ -51,7 +51,7 @@ if (&Module-Failure-Message != "unpack offset 10 is larger than input data lengt
 
 # Invalid destination data type
 &Tmp-String-1 := "%(unpack:%{Tmp-String-0} 0 thing)"
-if (&Tmp-String-1) {
+if !(&Tmp-String-1 == "") {
        test_fail
 }
 
@@ -61,7 +61,7 @@ if (&Module-Failure-Message != "Invalid data type 'thing'") {
 
 # Invalid source data type
 &Tmp-String-1 := "%(unpack:%{Tmp-Integer-0} 0 string)"
-if (&Tmp-String-1) {
+if !(&Tmp-String-1 == "") {
        test_fail
 }
 
@@ -74,7 +74,7 @@ if (&Module-Failure-Message != "unpack requires the input attribute to be 'strin
 &Tmp-String-0 := '0x014sdgw'
 &Tmp-String-1 := "%(unpack:%{Tmp-String-0} 0 string)"
 
-if (&Tmp-String-1) {
+if !(&Tmp-String-1 == "") {
        test_fail
 }
 
@@ -87,7 +87,7 @@ if (&Module-Failure-Message != "Invalid hex string in '0x014sdgw'") {
 &Tmp-String-0 := '0x'
 &Tmp-String-1 := "%(unpack:%{Tmp-String-0} 0 string)"
 
-if (&Tmp-String-1) {
+if !(&Tmp-String-1 == "") {
        test_fail
 }
 
index f44aeca93bbef5f9f2dd5a4785d49c7c3b3d7c92..3b71d90ca8811256cfcaf1b75acfd96381000e26 100644 (file)
@@ -49,7 +49,7 @@ if (&Tmp-String-1 != &Tmp-String-0) {
 }
 
 # Test decoding invalid encoded string
-if (&Tmp-String-2) {
+if !(&Tmp-String-2 == "") {
        test_fail
 }
 
index 851cd4c3f1c08525954f5a7e1d39752376bed459..fb5e7a2acf34e4ea7f3a00c494a7f664cd0e7ddc 100644 (file)
@@ -8,8 +8,8 @@
 #
 #  First choice
 #
-&Tmp-String-2 := "%{%{Tmp-String-0[0]}:-%{Tmp-String-1[0]}}"
-if (&Tmp-String-2[0] != 'foo') {
+&Tmp-String-2 := "%{%{Tmp-String-0}:-%{Tmp-String-1}}"
+if (&Tmp-String-2 != 'foo') {
        test_fail
 }
 
@@ -17,16 +17,16 @@ if (&Tmp-String-2[0] != 'foo') {
 #  Second choice
 #
 &request -= &Tmp-String-0[*]
-&Tmp-String-2 := "%{%{Tmp-String-0[0]}:-%{Tmp-String-1[0]}}"
-if (&Tmp-String-2[0] != 'bar') {
+&Tmp-String-2 := "%{%{Tmp-String-0}:-%{Tmp-String-1}}"
+if (&Tmp-String-2 != 'bar') {
        test_fail
 }
 
 #
 #  Multiple things in an alternation
 #
-&Tmp-String-2 := "%{%{Tmp-String-0[0]}:-%{Tmp-String-1[0]} foo}"
-if !(&Tmp-String-2[0] == 'bar foo') {
+&Tmp-String-2 := "%{%{Tmp-String-0}:-%{Tmp-String-1} foo}"
+if !(&Tmp-String-2 == 'bar foo') {
        test_fail
 }
 
@@ -37,11 +37,22 @@ if !(&Tmp-String-2[0] == 'bar foo') {
 &request -= &Tmp-String-2[*]
 
 #
-#  Both sides are failing, so the assignment here fails, too.
+#  Both sides are failing, so the assignment returns a NULL string
 #
-&Tmp-String-2 := "%{%{Tmp-String-0[0]}:-%{Tmp-String-1[0]}}"
-if (&Tmp-String-2[0]) {
+&Tmp-String-2 := "%{%{Tmp-String-0}:-%{Tmp-String-1}}"
+if !(&Tmp-String-2 == "") {
        test_fail
 }
 
+#
+#  And unquoted results return nothing.
+#
+&request -= &Tmp-String-2[*]
+
+&Tmp-String-2 := %{%{Tmp-String-0}:-%{Tmp-String-1}}
+if (&Tmp-String-2) {
+       test_fail
+}
+
+
 success
index 1cfaaadf695ec83bb24a136be8300022c18271ae..508147987ae1bb38e7aeed9f3f932c0d145eb62c 100644 (file)
@@ -26,13 +26,13 @@ if (&Tmp-String-0 != 'b_type') {
 #  Test non-existent client properties
 #
 &Tmp-String-3 := "%(client:non-existent-attr)"
-&Tmp-String-4 += "%(client:non-existing-attr2)"
+&Tmp-String-4 := "%(client:non-existing-attr2)"
 
-if (&Tmp-String-3) {
+if !(&Tmp-String-3 == "") {
        test_fail
 }
 
-if (&Tmp-String-4) {
+if !(&Tmp-String-4 == "") {
        test_fail
 }
 
index 80ebf21c13e0a9f47befb4ed430e2ea1e477b71b..2bba7443623c78161f0086e45fb219cc8347df72 100644 (file)
@@ -3,7 +3,7 @@
 #  because we don't wait for the response.
 #
 &Tmp-String-0 := "%(exec_async:/bin/sh -c 'echo -n hello')"
-if (&Tmp-String-0) {
+if !(&Tmp-String-0 == "") {
        test_fail
 }
 
@@ -26,6 +26,6 @@ if (&reply.Reply-Message == 'hello') {
 #  after the test exits.
 #
 &Tmp-String-0 := "%(exec_async:/bin/sh -c 'sleep 1')"
-if (&Tmp-String-0) {
+if !(&Tmp-String-0 == "") {
        test_fail
 }
index 51f8b3a01cc53b993d13fdcfbca77ed104f53472..b78d54305391633114b668d7d1ff29117d657ba0 100644 (file)
@@ -16,14 +16,14 @@ if (&Module-Failure-Message[*] != "Timeout running program - killing it and fail
        test_fail
 }
 
-if (&Tmp-String-0) {
+if !(&Tmp-String-0 == "") {
        test_fail
 }
 
 &request -= &Tmp-String-0
 &Tmp-String-0 := "%(exec_sync:/bin/sh $ENV{MODULE_TEST_DIR}/fail.sh)"
 
-if (&Tmp-String-0) {
+if !(&Tmp-String-0 == "") {
        test_fail
 }