]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
note that we can't do &list1 := &list2 + &list3
authorAlan T. DeKok <aland@freeradius.org>
Tue, 31 Oct 2023 14:47:24 +0000 (10:47 -0400)
committerAlan T. DeKok <aland@freeradius.org>
Tue, 31 Oct 2023 14:48:37 +0000 (10:48 -0400)
it's better to give a descriptive error than crash

src/lib/server/map.c
src/lib/unlang/xlat_expr.c
src/tests/keywords/list-add-error [new file with mode: 0644]

index 893dd242daf3f8b34771086360367722a7c3c395..2b81362844e746faae85cc4259689628d52604f3 100644 (file)
@@ -196,7 +196,7 @@ int map_afrom_cp(TALLOC_CTX *ctx, map_t **out, map_t *parent, CONF_PAIR *cp,
                rhs_rules = &my_rhs_rules;
 
                da = tmpl_attr_tail_da(map->lhs);
-               if (edit && fr_type_is_leaf(da->type)) my_rhs_rules.enumv = tmpl_attr_tail_da(map->lhs);
+               if (edit) my_rhs_rules.enumv = tmpl_attr_tail_da(map->lhs);
                break;
        }
 
@@ -246,6 +246,18 @@ int map_afrom_cp(TALLOC_CTX *ctx, map_t **out, map_t *parent, CONF_PAIR *cp,
                slen = talloc_array_length(value) - 1;
        }
 
+       /*
+        *      If we're assigning to a structural attribute, AND the
+        *      RHS side is a string, THEN don't parse the RHS as a
+        *      "group".  The edit code will take the string, create
+        *      pairs, and work on that.
+        */
+       if (edit && my_rhs_rules.enumv && fr_type_is_structural(my_rhs_rules.enumv->type) &&
+           ((type == T_DOUBLE_QUOTED_STRING) || (type == T_BACK_QUOTED_STRING) || (type == T_SINGLE_QUOTED_STRING))) {
+               my_rhs_rules.enumv = NULL;
+       }
+
+
        slen = tmpl_afrom_substr(map, &map->rhs,
                                 &FR_SBUFF_IN(value, slen),
                                 type,
index 548c3959cfea68117986471d5c2b70c302fa181b..79eac596ebb43c41c5f7e6d47642d0bdb876e3ce 100644 (file)
@@ -2720,14 +2720,25 @@ redo:
        XLAT_DEBUG("    operator <-- %pV", fr_box_strvalue_len(fr_sbuff_current(&our_in), fr_sbuff_remaining(&our_in)));
        fr_sbuff_out_by_longest_prefix(&slen, &op, expr_assignment_op_table, &our_in, T_INVALID);
        if (op == T_INVALID) {
+               fr_strerror_const("Invalid operator");
                talloc_free(lhs);
-               fr_strerror_printf("Invalid operator");
                FR_SBUFF_ERROR_RETURN(&our_in);
        }
 
        if (!binary_ops[op].str) {
-               fr_strerror_printf("Invalid operator");
+               fr_strerror_const("Invalid operator");
                fr_sbuff_set(&our_in, &m_op);
+               talloc_free(lhs);
+               FR_SBUFF_ERROR_RETURN(&our_in);
+       }
+
+       /*
+        *      We can't (yet) do &list1 = &list2 + &list3
+        */
+       if (fr_binary_op[op] && t_rules->enumv && fr_type_is_structural(t_rules->enumv->type)) {
+               fr_strerror_const("Invalid operator for structural attribute");
+               fr_sbuff_set(&our_in, &m_op);
+               talloc_free(lhs);
                FR_SBUFF_ERROR_RETURN(&our_in);
        }
 
diff --git a/src/tests/keywords/list-add-error b/src/tests/keywords/list-add-error
new file mode 100644 (file)
index 0000000..dc4c346
--- /dev/null
@@ -0,0 +1,3 @@
+group foo
+
+&foo := &request + &control # ERROR