]> git.ipfire.org Git - thirdparty/freeradius-server.git/commitdiff
expose fr_cond_promote_types() and call it from unlang pass2
authorAlan T. DeKok <aland@freeradius.org>
Sat, 9 Jan 2021 20:46:37 +0000 (15:46 -0500)
committerAlan T. DeKok <aland@freeradius.org>
Sat, 9 Jan 2021 20:46:37 +0000 (15:46 -0500)
so that we can do all of the normalizations / checks necessary,
and not just whatever hacks have gone into the compiler

src/lib/server/cond.h
src/lib/server/cond_tokenize.c
src/lib/unlang/compile.c

index e826fefff284ac6ea4d0e1e4b1745d5c1d72284f..1e56884cf9fe4ba7e372b6fd224f1c76a0c328c3 100644 (file)
@@ -96,6 +96,8 @@ struct fr_cond_s {
 
 ssize_t        fr_cond_tokenize(CONF_SECTION *cs, fr_cond_t **head, tmpl_rules_t const *rules, fr_sbuff_t *in) CC_HINT(nonnull(1,2,4));
 
+int    fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs, fr_sbuff_marker_t *m_rhs) CC_HINT(nonnull(1));
+
 ssize_t        cond_print(fr_sbuff_t *out, fr_cond_t const *c);
 
 bool fr_cond_walk(fr_cond_t *head, bool (*callback)(fr_cond_t *cond, void *uctx), void *uctx);
index 5b1d17589cbb6f6a536d78ec5f8d17d78f730312..ce452eb87e60dfbcfe9e84615f00b5efe2dca4c7 100644 (file)
@@ -228,7 +228,7 @@ static int cond_cast_tmpl(tmpl_t *vpt, fr_type_t *p_type, tmpl_t *other)
 /** Promote the types in a FOO OP BAR comparison.
  *
  */
-static int cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs, fr_sbuff_marker_t *m_rhs)
+int fr_cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m_lhs, fr_sbuff_marker_t *m_rhs)
 {
        fr_type_t lhs_type, rhs_type;
        fr_type_t cast_type;
@@ -255,7 +255,7 @@ static int cond_promote_types(fr_cond_t *c, fr_sbuff_t *in, fr_sbuff_marker_t *m
                if (c->data.map->rhs->cast != FR_TYPE_INVALID) {
                        if (c->data.map->rhs->cast != lhs_type) {
                                fr_strerror_const("Incompatible casts");
-                               fr_sbuff_set(in, fr_sbuff_start(in));
+                               if (in) fr_sbuff_set(in, fr_sbuff_start(in));
                                return -1;
                        }
 
@@ -360,12 +360,12 @@ set_types:
         *      Cast both sides to the promoted type.
         */
        if (cond_cast_tmpl(c->data.map->lhs, &cast_type, c->data.map->rhs) < 0) {
-               fr_sbuff_set(in, m_lhs);
+               if (in) fr_sbuff_set(in, m_lhs);
                return -1;
        }
 
        if (cond_cast_tmpl(c->data.map->rhs, &cast_type, c->data.map->lhs) < 0) {
-               fr_sbuff_set(in, m_rhs);
+               if (in) fr_sbuff_set(in, m_rhs);
                return -1;
        }
 
@@ -1375,7 +1375,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out,
                 *      Promote the data types to the appropriate
                 *      values.
                 */
-               if (cond_promote_types(c, &our_in, &m_lhs, &m_rhs) < 0) {
+               if (fr_cond_promote_types(c, &our_in, &m_lhs, &m_rhs) < 0) {
                        goto error;
                }
        } /* parse OP RHS */
index bd66613a010db95981cbba0137686918f4d06dbf..f0b68f11f6888edfa5e64b75992157168a12e879 100644 (file)
@@ -222,77 +222,24 @@ static bool pass2_fixup_cond_map(fr_cond_t *c, CONF_ITEM *ci)
        }
 
        if (c->pass2_fixup == PASS2_FIXUP_ATTR) {
-               fr_type_t cast_type = c->data.map->lhs->cast;
-
                /*
                 *      Resolve the attribute references first
                 */
                if (tmpl_is_attr_unresolved(map->lhs)) {
                        if (!pass2_fixup_tmpl(map, map->ci, &map->lhs)) return false;
-                       if (cast_type == FR_TYPE_INVALID) cast_type = tmpl_da(map->lhs)->type;
                }
 
                if (tmpl_is_attr_unresolved(map->rhs)) {
                        if (!pass2_fixup_tmpl(map, map->ci, &map->rhs)) return false;
-                       if (cast_type == FR_TYPE_INVALID) cast_type = tmpl_da(map->rhs)->type;
                }
 
                /*
-                *      Then fixup the other side if it was unresolved
+                *      Now that we have known data types for the LHS
+                *      / RHS attribute(s), go check them.
                 */
-               if (tmpl_is_unresolved(map->lhs)) {
-                       switch (cast_type) {
-                       case FR_TYPE_IPV4_ADDR:
-                               if (strchr(c->data.map->lhs->name, '/') != NULL) {
-                                       cast_type = FR_TYPE_IPV4_PREFIX;
-                                       tmpl_cast_set(c->data.map->lhs, cast_type);
-                               }
-                               break;
-
-                       case FR_TYPE_IPV6_ADDR:
-                               if (strchr(c->data.map->lhs->name, '/') != NULL) {
-                                       cast_type = FR_TYPE_IPV6_PREFIX;
-                                       tmpl_cast_set(c->data.map->lhs, cast_type);
-                               }
-                               break;
-
-                       default:
-                               break;
-                       }
-
-                       if (tmpl_cast_in_place(c->data.map->lhs, cast_type, NULL) < 0) {
-                               cf_log_err(map->ci, "Failed to parse data type %s from string: %pV",
-                                          fr_table_str_by_value(fr_value_box_type_table, cast_type, "<UNKNOWN>"),
-                                          fr_box_strvalue_len(map->lhs->name, map->lhs->len));
-
-                               return false;
-                       }
-               } else if (tmpl_is_unresolved(map->rhs)) {
-                       switch (cast_type) {
-                       case FR_TYPE_IPV4_ADDR:
-                               if (strchr(c->data.map->rhs->name, '/') != NULL) {
-                                       cast_type = FR_TYPE_IPV4_PREFIX;
-                                       tmpl_cast_set(c->data.map->lhs, cast_type);
-                               }
-                               break;
-
-                       case FR_TYPE_IPV6_ADDR:
-                               if (strchr(c->data.map->rhs->name, '/') != NULL) {
-                                       cast_type = FR_TYPE_IPV6_PREFIX;
-                                       tmpl_cast_set(c->data.map->lhs, cast_type);
-                               }
-                               break;
-
-                       default:
-                               break;
-                       }
-
-                       if (tmpl_cast_in_place(c->data.map->rhs, cast_type, NULL) < 0) {
-                               cf_log_err(map->ci, "Failed to parse data type %s from string: %pV",
-                                          fr_table_str_by_value(fr_value_box_type_table, cast_type, "<UNKNOWN>"),
-                                          fr_box_strvalue_len(map->rhs->name, map->rhs->len));
-                               return false;
-                       }
+               if (fr_cond_promote_types(c, NULL, NULL, NULL) < 0) {
+                       cf_log_err(ci, "Failed parsing condition after dynamic attributes were defined.");
+                       return false;
                }
 
                c->pass2_fixup = PASS2_FIXUP_NONE;