From: Alan T. DeKok Date: Sat, 9 Jan 2021 20:46:37 +0000 (-0500) Subject: expose fr_cond_promote_types() and call it from unlang pass2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=454a415e268c7bde9949553b062a9384e07cb516;p=thirdparty%2Ffreeradius-server.git expose fr_cond_promote_types() and call it from unlang pass2 so that we can do all of the normalizations / checks necessary, and not just whatever hacks have gone into the compiler --- diff --git a/src/lib/server/cond.h b/src/lib/server/cond.h index e826fefff28..1e56884cf9f 100644 --- a/src/lib/server/cond.h +++ b/src/lib/server/cond.h @@ -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); diff --git a/src/lib/server/cond_tokenize.c b/src/lib/server/cond_tokenize.c index 5b1d17589cb..ce452eb87e6 100644 --- a/src/lib/server/cond_tokenize.c +++ b/src/lib/server/cond_tokenize.c @@ -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 */ diff --git a/src/lib/unlang/compile.c b/src/lib/unlang/compile.c index bd66613a010..f0b68f11f68 100644 --- a/src/lib/unlang/compile.c +++ b/src/lib/unlang/compile.c @@ -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, ""), - 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, ""), - 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;