From: Alan T. DeKok Date: Tue, 7 Jun 2022 22:42:20 +0000 (-0400) Subject: hacks to check input terminal sequences. X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e5ed4bde8e235891ec32cef8adc1e31fe392a1c0;p=thirdparty%2Ffreeradius-server.git hacks to check input terminal sequences. These really need to be cleaned up, as when we're in the middle of parsing an expression like (foo......) we do NOT want to pay attention to input terminals. We've hit our tokenizer, and WE decide what the tokens are. --- diff --git a/src/lib/unlang/xlat_expr.c b/src/lib/unlang/xlat_expr.c index 362e1a1092e..b5f8aa8dd43 100644 --- a/src/lib/unlang/xlat_expr.c +++ b/src/lib/unlang/xlat_expr.c @@ -1441,11 +1441,13 @@ static const int precedence[T_TOKEN_LAST] = { static ssize_t tokenize_expression(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, - fr_token_t prev, fr_sbuff_parse_rules_t const *bracket_rules, bool expect_regex); + fr_token_t prev, fr_sbuff_parse_rules_t const *bracket_rules, + fr_sbuff_parse_rules_t const *input_rules, bool expect_regex, int depth); static ssize_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, - fr_sbuff_parse_rules_t const *bracket_rules, bool expect_regex); + fr_sbuff_parse_rules_t const *bracket_rules, + fr_sbuff_parse_rules_t const *input_rules, bool expect_regex, int depth); static fr_table_num_sorted_t const expr_quote_table[] = { { L("\""), T_DOUBLE_QUOTED_STRING }, /* Don't re-order, backslash throws off ordering */ @@ -1471,7 +1473,8 @@ static size_t expr_quote_table_len = NUM_ELEMENTS(expr_quote_table); */ static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, - fr_sbuff_parse_rules_t const *bracket_rules, bool expect_regex) + fr_sbuff_parse_rules_t const *bracket_rules, + fr_sbuff_parse_rules_t const *input_rules, bool expect_regex, int depth) { ssize_t slen; xlat_exp_t *node = NULL, *unary = NULL; @@ -1527,7 +1530,7 @@ static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ * that we return that, and not the child node */ if (!func) { - return tokenize_field(head, out, in, p_rules, t_rules, bracket_rules, expect_regex); + return tokenize_field(head, out, in, p_rules, t_rules, bracket_rules, input_rules, expect_regex, depth); } MEM(unary = xlat_exp_alloc(head, XLAT_FUNC, func->name, strlen(func->name))); @@ -1536,8 +1539,8 @@ static ssize_t tokenize_unary(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ unary->call.func = func; unary->flags = func->flags; - slen = tokenize_field(unary->call.args, &node, &our_in, p_rules, t_rules, bracket_rules, expect_regex); - if (slen <= 0) { + slen = tokenize_field(unary->call.args, &node, &our_in, p_rules, t_rules, bracket_rules, input_rules, expect_regex, depth); + if (slen < 0) { talloc_free(unary); FR_SBUFF_ERROR_RETURN_ADJ(&our_in, slen); } @@ -1608,7 +1611,8 @@ static ssize_t expr_cast_from_substr(fr_type_t *cast, fr_sbuff_t *in) */ static ssize_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, - fr_sbuff_parse_rules_t const *bracket_rules, bool expect_regex) + fr_sbuff_parse_rules_t const *bracket_rules, + fr_sbuff_parse_rules_t const *input_rules, bool expect_regex, int depth) { ssize_t slen; xlat_exp_t *node = NULL; @@ -1641,7 +1645,7 @@ static ssize_t tokenize_field(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_ * value when we get the output of the expression. */ if (fr_sbuff_next_if_char(&our_in, '(')) { - slen = tokenize_expression(head, &node, &our_in, bracket_rules, t_rules, T_INVALID, bracket_rules, false); + slen = tokenize_expression(head, &node, &our_in, bracket_rules, t_rules, T_INVALID, bracket_rules, input_rules, false, depth + 1); if (slen <= 0) { FR_SBUFF_ERROR_RETURN_ADJ(&our_in, slen); } @@ -1995,7 +1999,8 @@ static int reparse_rcode(TALLOC_CTX *ctx, xlat_exp_t **p_arg, bool allow) */ static ssize_t tokenize_expression(xlat_exp_head_t *head, xlat_exp_t **out, fr_sbuff_t *in, fr_sbuff_parse_rules_t const *p_rules, tmpl_rules_t const *t_rules, - fr_token_t prev, fr_sbuff_parse_rules_t const *bracket_rules, bool expect_regex) + fr_token_t prev, fr_sbuff_parse_rules_t const *bracket_rules, + fr_sbuff_parse_rules_t const *input_rules, bool expect_regex, int depth) { xlat_exp_t *lhs = NULL, *rhs = NULL, *node; xlat_t *func = NULL; @@ -2015,12 +2020,17 @@ static ssize_t tokenize_expression(xlat_exp_head_t *head, xlat_exp_t **out, fr_s * Get the LHS of the operation. */ if (expect_regex) { - slen = tokenize_field(head, &lhs, &our_in, p_rules, t_rules, bracket_rules, expect_regex); + slen = tokenize_field(head, &lhs, &our_in, p_rules, t_rules, bracket_rules, input_rules, expect_regex, depth); } else { - slen = tokenize_unary(head, &lhs, &our_in, p_rules, t_rules, bracket_rules, false); + slen = tokenize_unary(head, &lhs, &our_in, p_rules, t_rules, bracket_rules, input_rules, false, depth); } - if (slen <= 0) return slen; + if (slen < 0) return slen; + if (slen == 0) { + fr_assert(lhs == NULL); + *out = NULL; + return fr_sbuff_set(in, &our_in); + } redo: #ifdef __clang_analyzer__ @@ -2057,6 +2067,11 @@ redo: } fr_sbuff_skip_whitespace(&our_in); + /* + * We hit a terminal sequence, stop. + */ + if (input_rules && (depth == 0) && fr_sbuff_is_terminal(&our_in, input_rules->terminals)) goto done; + /* * Remember where we were after parsing the LHS. */ @@ -2099,8 +2114,8 @@ redo: * We now parse the RHS, allowing a (perhaps different) cast on the RHS. */ XLAT_DEBUG(" recurse RHS <-- %pV", fr_box_strvalue_len(fr_sbuff_current(&our_in), fr_sbuff_remaining(&our_in))); - slen = tokenize_expression(head, &rhs, &our_in, p_rules, t_rules, op, bracket_rules, - ((op == T_OP_REG_EQ) || (op == T_OP_REG_NE))); + slen = tokenize_expression(head, &rhs, &our_in, p_rules, t_rules, op, bracket_rules, input_rules, + ((op == T_OP_REG_EQ) || (op == T_OP_REG_NE)), depth); if (slen <= 0) { talloc_free(lhs); FR_SBUFF_ERROR_RETURN_ADJ(&our_in, slen); @@ -2273,7 +2288,7 @@ ssize_t xlat_tokenize_expression(TALLOC_CTX *ctx, xlat_exp_head_t **out, fr_sbuf t_rules = &my_rules; } - slen = tokenize_expression(head, &node, in, terminal_rules, t_rules, T_INVALID, bracket_rules, false); + slen = tokenize_expression(head, &node, in, terminal_rules, t_rules, T_INVALID, bracket_rules, p_rules, false, 0); talloc_free(bracket_rules); talloc_free(terminal_rules); @@ -2373,7 +2388,7 @@ ssize_t xlat_tokenize_ephemeral_expression(TALLOC_CTX *ctx, xlat_exp_head_t **ou my_rules.xlat.runtime_el = el; my_rules.at_runtime = true; - slen = tokenize_expression(head, &node, in, terminal_rules, &my_rules, T_INVALID, bracket_rules, false); + slen = tokenize_expression(head, &node, in, terminal_rules, &my_rules, T_INVALID, bracket_rules, p_rules, false, 0); talloc_free(bracket_rules); talloc_free(terminal_rules);