From: Alan T. DeKok Date: Tue, 21 Jun 2022 15:26:19 +0000 (-0400) Subject: more clearly separate pre/post expansion parsing. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7dbf85df575e42214a5fd4f31f4161acabeee168;p=thirdparty%2Ffreeradius-server.git more clearly separate pre/post expansion parsing. We first parse the condition *without* doing variable expansion. this lets us know how big the condition is. We then expand the variables and re-parse the condition. This two-pass method is a temporary hack until we get the new xlat expressions working. --- diff --git a/src/bin/unit_test_attribute.c b/src/bin/unit_test_attribute.c index 295d7516735..50a4ae27ede 100644 --- a/src/bin/unit_test_attribute.c +++ b/src/bin/unit_test_attribute.c @@ -1448,7 +1448,7 @@ static size_t command_condition_normalise(command_result_t *result, command_file cf_filename_set(cs, cc->filename); cf_lineno_set(cs, cc->lineno); - dec_len = fr_cond_tokenize(cs, &cond, &cc->tmpl_rules, &FR_SBUFF_IN(in, inlen)); + dec_len = fr_cond_tokenize(cs, &cond, &cc->tmpl_rules, &FR_SBUFF_IN(in, inlen), false); if (dec_len <= 0) { fr_strerror_printf_push_head("ERROR offset %d", (int) -dec_len); diff --git a/src/lib/server/cf_file.c b/src/lib/server/cf_file.c index e9d9ee8f157..bc505c6e569 100644 --- a/src/lib/server/cf_file.c +++ b/src/lib/server/cf_file.c @@ -1211,12 +1211,14 @@ static CONF_ITEM *process_if(cf_stack_t *stack) ssize_t end; char *spaces, *text; + ERROR("INPUT %s", ptr); + /* * Parse the condition. If it succeeded, stop * trying to expand the buffer. */ slen = fr_cond_tokenize(cs, &cond, - &t_rules, &FR_SBUFF_IN(ptr, strlen(ptr))); + &t_rules, &FR_SBUFF_IN(ptr, strlen(ptr)), true); if (slen > 0) break; end = -slen; @@ -1271,7 +1273,7 @@ static CONF_ITEM *process_if(cf_stack_t *stack) * condition, expand the variables, and reparse the * condition. */ - if (strchr(ptr, '$') != NULL) { + { ssize_t my_slen; talloc_free(cond); @@ -1282,7 +1284,7 @@ static CONF_ITEM *process_if(cf_stack_t *stack) return NULL; } - my_slen = fr_cond_tokenize(cs, &cond, &t_rules, &FR_SBUFF_IN(buff[3], strlen(buff[3]))); + my_slen = fr_cond_tokenize(cs, &cond, &t_rules, &FR_SBUFF_IN(buff[3], strlen(buff[3])), false); if (my_slen <= 0) { ptr = buff[3]; slen = my_slen; @@ -1296,15 +1298,6 @@ static CONF_ITEM *process_if(cf_stack_t *stack) slen = my_slen; goto parse_error; } - } else { - ssize_t my_slen; - - my_slen = xlat_tokenize_expression(cs, &head, &FR_SBUFF_IN(buff[2], strlen(buff[2])), &p_rules, &t_rules); - if (my_slen <= 0) { - ptr = buff[2]; - slen = my_slen; - goto parse_error; - } #endif } diff --git a/src/lib/server/cond.h b/src/lib/server/cond.h index fb8a532bf04..1bdbe6eb475 100644 --- a/src/lib/server/cond.h +++ b/src/lib/server/cond.h @@ -99,9 +99,9 @@ typedef struct { fr_cond_t *cond; } fr_cond_iter_t; -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)); +ssize_t fr_cond_tokenize(CONF_SECTION *cs, fr_cond_t **head, tmpl_rules_t const *rules, fr_sbuff_t *in, bool flag) 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)); +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, bool flag) CC_HINT(nonnull(1)); ssize_t cond_print(fr_sbuff_t *out, fr_cond_t const *c); diff --git a/src/lib/server/cond_tokenize.c b/src/lib/server/cond_tokenize.c index 4f9b9784731..eb58c2c6866 100644 --- a/src/lib/server/cond_tokenize.c +++ b/src/lib/server/cond_tokenize.c @@ -211,7 +211,7 @@ static int cond_cast_tmpl(tmpl_t *vpt, fr_type_t type, tmpl_t *other) /** Promote the types in a FOO OP BAR comparison. * */ -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) +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, bool flag) { fr_type_t lhs_type, rhs_type; fr_type_t cast_type; @@ -482,6 +482,11 @@ set_types: } } + /* + * Skip casting. + */ + if (flag) return 0; + /* * Cast both sides to the promoted type. */ @@ -1070,13 +1075,14 @@ static ssize_t cond_tokenize_operand(fr_cond_t *c, tmpl_t **out, * @param[in] in the start of the string to process. Should be "(..." * @param[in] brace look for a closing brace (how many deep we are) * @param[in] t_rules for attribute parsing + * @param[in] flag temporary hack * @return * - Length of the string skipped. * - < 0 (the offset to the offending error) on error. */ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, CONF_SECTION *cs, fr_sbuff_t *in, int brace, - tmpl_rules_t const *t_rules) + tmpl_rules_t const *t_rules, bool flag) { fr_sbuff_t our_in = FR_SBUFF(in); ssize_t slen; @@ -1127,7 +1133,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, /* * Children are allocated from the parent. */ - slen = cond_tokenize(c, &c->data.child, cs, &our_in, brace + 1, t_rules); + slen = cond_tokenize(c, &c->data.child, cs, &our_in, brace + 1, t_rules, flag); if (slen <= 0) { fr_sbuff_advance(&our_in, slen * -1); goto error; @@ -1351,7 +1357,7 @@ static ssize_t cond_tokenize(TALLOC_CTX *ctx, fr_cond_t **out, * Promote the data types to the appropriate * values. */ - if (fr_cond_promote_types(c, &our_in, &m_lhs, &m_rhs) < 0) { + if (fr_cond_promote_types(c, &our_in, &m_lhs, &m_rhs, flag) < 0) { goto error; } } /* parse OP RHS */ @@ -1423,7 +1429,7 @@ closing_brace: * siblings are allocated from their older * siblings. */ - slen = cond_tokenize(child, &child->next, cs, &our_in, brace, t_rules); + slen = cond_tokenize(child, &child->next, cs, &our_in, brace, t_rules, flag); if (slen <= 0) { fr_sbuff_advance(&our_in, slen * -1); goto error; @@ -1439,7 +1445,7 @@ closing_brace: * siblings are allocated from their older * siblings. */ - slen = cond_tokenize(c, &c->next, cs, &our_in, brace, t_rules); + slen = cond_tokenize(c, &c->next, cs, &our_in, brace, t_rules, flag); if (slen <= 0) { fr_sbuff_advance(&our_in, slen * -1); goto error; @@ -1480,18 +1486,19 @@ static void cond_reparent(fr_cond_t *c, fr_cond_t *parent) * @param[out] head the parsed condition structure * @param[in] rules for parsing operands. * @param[in] in the start of the string to process. + * @param[in] flag temporary hack * @return * - Length of the string skipped. * - < 0 (the offset to the offending error) on error. */ -ssize_t fr_cond_tokenize(CONF_SECTION *cs, fr_cond_t **head, tmpl_rules_t const *rules, fr_sbuff_t *in) +ssize_t fr_cond_tokenize(CONF_SECTION *cs, fr_cond_t **head, tmpl_rules_t const *rules, fr_sbuff_t *in, bool flag) { ssize_t slen; fr_sbuff_t our_in = FR_SBUFF(in); *head = NULL; - slen = cond_tokenize(cs, head, cs, &our_in, 0, rules); + slen = cond_tokenize(cs, head, cs, &our_in, 0, rules, flag); if (slen <= 0) return slen; /* diff --git a/src/lib/unlang/compile.c b/src/lib/unlang/compile.c index f1c8f6c0baa..76170b74a66 100644 --- a/src/lib/unlang/compile.c +++ b/src/lib/unlang/compile.c @@ -303,7 +303,7 @@ static bool pass2_fixup_cond_map(fr_cond_t *c, CONF_ITEM *ci, fr_dict_t const *d * Now that we have known data types for the LHS * / RHS attribute(s), go check them. */ - if (fr_cond_promote_types(c, NULL, NULL, NULL) < 0) { + if (fr_cond_promote_types(c, NULL, NULL, NULL, false) < 0) { cf_log_perr(ci, "Failed parsing condition after dynamic attributes were defined"); return false; }