]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
empty strings are empty lists
authorAlan T. DeKok <aland@freeradius.org>
Mon, 2 Sep 2024 15:51:21 +0000 (11:51 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Mon, 2 Sep 2024 18:00:20 +0000 (14:00 -0400)
so that we don't get confused when the debug output prints

cmp({},{}) --> false

because it's really instead

cmp({''},{})

which is an empty string on one side, and an empty set on the other.

src/lib/util/calc.c
src/tests/keywords/xlat-cond-missing

index c024afc9f6e967df05759d089ac5ae1f9a8ee7d7..264ce3dd04a3ef5029c4ee5e4ac6734e5de87df2 100644 (file)
@@ -2645,6 +2645,37 @@ brute_force:
        return 0;
 }
 
+/*
+ *     Empty lists are empty:
+ *
+ *             {}
+ *             {{}}
+ *             {''}
+ *             {{},''}
+ *
+ *             etc.
+ */
+static bool fr_value_calc_list_empty(fr_value_box_list_t const *list)
+{
+       fr_value_box_list_foreach(list, item) {
+               switch (item->type) {
+               default:
+                       return false;
+
+               case FR_TYPE_GROUP:
+                       if (!fr_value_calc_list_empty(&item->vb_group)) return false;
+                       break;
+
+               case FR_TYPE_STRING:
+               case FR_TYPE_OCTETS:
+                       if (item->vb_length != 0) return false;
+                       break;
+               }
+       }
+
+       return true;
+}
+
 
 /*
  *     Loop over input lists, calling fr_value_calc_binary_op()
@@ -2656,6 +2687,7 @@ int fr_value_calc_list_cmp(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_li
 {
        int rcode;
        bool invert = false;
+       bool a_empty, b_empty;
 
        /*
         *      v3 hack.  != really means !( ... == ... )
@@ -2665,11 +2697,20 @@ int fr_value_calc_list_cmp(TALLOC_CTX *ctx, fr_value_box_t *dst, fr_value_box_li
                op = T_OP_CMP_EQ;
        }
 
+       /*
+        *      It's annoying when the debug prints out cmp({},{}) and says "not equal".
+        *
+        *      What's happening behind the scenes is that one side is an empty value-box group, such as when
+        *      an xlat expansion fails.  And the other side is an empty string.  If we believe that strings
+        *      are actually sets of characters, then {}=='', and we're all OK
+        */
+       a_empty = fr_value_box_list_empty(list1) || fr_value_calc_list_empty(list1);
+       b_empty = fr_value_box_list_empty(list2) || fr_value_calc_list_empty(list2);
+
        /*
         *      Both lists are empty, they should be equal when checked for equality.
         */
-       if ((fr_value_box_list_num_elements(list1) == 0) &&
-           (fr_value_box_list_num_elements(list2) == 0)) {
+       if (a_empty && b_empty) {
                switch (op) {
                case T_OP_CMP_EQ:
                case T_OP_LE:
index ec0fa3479c3d7bb648a2221d8ad59b2a9b250fdd..20bc648342332fd563522fdba6ba1c1a59c19a44 100644 (file)
@@ -16,7 +16,7 @@ if (%{Framed-IP-Address[#]} != 4) {
 #  for the existence of the attribute.  But... the syntax allows it, so
 #  it should work.
 #
-if !("%{Framed-IP-Address[4]}" == '') {
+if ("%{Framed-IP-Address[4]}" != '') {
        test_fail
 }